11cf9b237SStefano 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 91cf9b237SStefano Zampini /* TODO: add reuse flag */ 101cf9b237SStefano Zampini #undef __FUNCT__ 111cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 121cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 131cf9b237SStefano Zampini { 141cf9b237SStefano Zampini Mat Bt; 151cf9b237SStefano Zampini PetscScalar *a,*bdata; 161cf9b237SStefano Zampini const PetscInt *ii,*ij; 171cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 181cf9b237SStefano Zampini PetscBool flg_row; 191cf9b237SStefano Zampini PetscErrorCode ierr; 201cf9b237SStefano Zampini 211cf9b237SStefano Zampini PetscFunctionBegin; 221cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 231cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 241cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 251cf9b237SStefano Zampini nnz = n; 261cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 271cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 281cf9b237SStefano Zampini } 291cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 301cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 311cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 321cf9b237SStefano Zampini nnz = 0; 331cf9b237SStefano Zampini bii[0] = 0; 341cf9b237SStefano Zampini for (i=0;i<n;i++) { 351cf9b237SStefano Zampini PetscInt j; 361cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 371cf9b237SStefano Zampini PetscScalar entry = a[j]; 381cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 391cf9b237SStefano Zampini bij[nnz] = ij[j]; 401cf9b237SStefano Zampini bdata[nnz] = entry; 411cf9b237SStefano Zampini nnz++; 421cf9b237SStefano Zampini } 431cf9b237SStefano Zampini } 441cf9b237SStefano Zampini bii[i+1] = nnz; 451cf9b237SStefano Zampini } 461cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 471cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 481cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 491cf9b237SStefano Zampini { 501cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 511cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 521cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 531cf9b237SStefano Zampini } 541cf9b237SStefano Zampini *B = Bt; 551cf9b237SStefano Zampini PetscFunctionReturn(0); 561cf9b237SStefano Zampini } 571cf9b237SStefano 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) { 751cf9b237SStefano Zampini PetscBool isseqdense; 761cf9b237SStefano Zampini 771cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 781cf9b237SStefano Zampini if (!isseqdense) { 794f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 801cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 811cf9b237SStefano Zampini PetscScalar *array; 821cf9b237SStefano Zampini PetscReal chop=1.e-6; 831cf9b237SStefano Zampini 841cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 851cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 861cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 871cf9b237SStefano Zampini for (i=0;i<n;i++) { 881cf9b237SStefano Zampini PetscInt j; 891cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 901cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 911cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 921cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 931cf9b237SStefano Zampini } 941cf9b237SStefano Zampini } 951cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 961cf9b237SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); 971cf9b237SStefano 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); 1501cf9b237SStefano Zampini if (A != B) { 1514f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1524f1b2e48SStefano Zampini } 1534f1b2e48SStefano Zampini 1544f1b2e48SStefano Zampini /* get back data */ 1551cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 1561cf9b237SStefano 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; 1621cf9b237SStefano 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; 256*9f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 257*9f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 258339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 259339f8db1SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->local_mat);CHKERRQ(ierr); 260339f8db1SStefano Zampini pcbddc->benign_original_mat = pcbddc->local_mat; 2614f1b2e48SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures" 2624f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 2634f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 2644f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 2654f1b2e48SStefano Zampini since the local Schur complements are SPD 2664f1b2e48SStefano Zampini */ 2674f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 2684f1b2e48SStefano Zampini have_null = PETSC_TRUE; 26940fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 2704f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 2714f1b2e48SStefano Zampini 2724f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 2734f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 2744f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 2754f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 276ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 27740fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 27840fa8d13SStefano Zampini if (!sorted) { 27940fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 28040fa8d13SStefano Zampini } 28140fa8d13SStefano Zampini } else { 28240fa8d13SStefano Zampini pressures = NULL; 28340fa8d13SStefano Zampini } 2844f1b2e48SStefano Zampini ierr = MatGetLocalSize(pcbddc->benign_original_mat,&n,NULL);CHKERRQ(ierr); 2854f1b2e48SStefano Zampini /* TODO: add check for shared dofs and raise error */ 286339f8db1SStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->benign_original_mat,&zerodiag);CHKERRQ(ierr); 287339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 288339f8db1SStefano Zampini if (!sorted) { 289339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 290339f8db1SStefano Zampini } 291339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2924f1b2e48SStefano Zampini if (!nz) { 2934f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 2944f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 29540fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 29640fa8d13SStefano Zampini } 2974f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2984f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 2994f1b2e48SStefano Zampini zerodiag_subs = NULL; 3004f1b2e48SStefano Zampini pcbddc->benign_n = 0; 3014f1b2e48SStefano Zampini if (has_null_pressures) { 3024f1b2e48SStefano Zampini IS *subs; 3034f1b2e48SStefano Zampini PetscInt nsubs,i; 3044f1b2e48SStefano Zampini 3054f1b2e48SStefano Zampini subs = pcbddc->local_subs; 3064f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 3074f1b2e48SStefano Zampini if (nsubs > 1) { 3084f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 3094f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 3104f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 3114f1b2e48SStefano Zampini IS t_zerodiag_subs; 3124f1b2e48SStefano Zampini PetscInt nl; 3134f1b2e48SStefano Zampini 3144f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 3154f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 3164f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 3174f1b2e48SStefano Zampini if (nl) { 3184f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 3194f1b2e48SStefano Zampini 3204f1b2e48SStefano Zampini if (pressures) { 3214f1b2e48SStefano Zampini IS t_pressure_subs; 3224f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 3234f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 3244f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 3254f1b2e48SStefano Zampini } 3264f1b2e48SStefano Zampini if (valid) { 3274f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 3284f1b2e48SStefano Zampini pcbddc->benign_n++; 3294f1b2e48SStefano Zampini } else { 3304f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 3314f1b2e48SStefano Zampini } 3324f1b2e48SStefano Zampini } 3334f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 3344f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 3354f1b2e48SStefano Zampini } 3364f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 3374f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 3384f1b2e48SStefano Zampini if (pressures) { 3394f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 3404f1b2e48SStefano Zampini } 3414f1b2e48SStefano Zampini if (valid) { 3424f1b2e48SStefano Zampini pcbddc->benign_n = 1; 3434f1b2e48SStefano Zampini ierr = PetscCalloc1(1,&zerodiag_subs);CHKERRQ(ierr); 3444f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 3454f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 3464f1b2e48SStefano Zampini } 3474f1b2e48SStefano Zampini } 3484f1b2e48SStefano Zampini } 3494f1b2e48SStefano Zampini 3504f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 3514f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 3524f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 3534f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 3544f1b2e48SStefano Zampini have_null = PETSC_FALSE; 3554f1b2e48SStefano Zampini } 3564f1b2e48SStefano Zampini 3574f1b2e48SStefano Zampini /* final check for null pressures */ 3584f1b2e48SStefano Zampini if (zerodiag && pressures) { 3594f1b2e48SStefano Zampini PetscInt nz,np; 3604f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 3614f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 3624f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 3634f1b2e48SStefano Zampini } 3644f1b2e48SStefano Zampini 3654f1b2e48SStefano Zampini if (recompute_zerodiag) { 3664f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 3674f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 3684f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 3694f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 3704f1b2e48SStefano Zampini } else { 3714f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 3724f1b2e48SStefano Zampini 3734f1b2e48SStefano Zampini nzn = 0; 3744f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3754f1b2e48SStefano Zampini PetscInt ns; 3764f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 3774f1b2e48SStefano Zampini nzn += ns; 3784f1b2e48SStefano Zampini } 3794f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 3804f1b2e48SStefano Zampini nzn = 0; 3814f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3824f1b2e48SStefano Zampini PetscInt ns,*idxs; 3834f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 3844f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3854f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 3864f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3874f1b2e48SStefano Zampini nzn += ns; 3884f1b2e48SStefano Zampini } 3894f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 3904f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 3914f1b2e48SStefano Zampini } 3924f1b2e48SStefano Zampini have_null = PETSC_FALSE; 3934f1b2e48SStefano Zampini } 3944f1b2e48SStefano Zampini 3954f1b2e48SStefano Zampini if (has_null_pressures) { 3964f1b2e48SStefano Zampini IS zerodiagc; 3974f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 3984f1b2e48SStefano Zampini PetscInt i,s,*nnz; 3991cf9b237SStefano Zampini Mat M; 4004f1b2e48SStefano Zampini 4014f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 402339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 403339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 404339f8db1SStefano Zampini /* local change of basis for pressures */ 405339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 406339f8db1SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->benign_original_mat),&pcbddc->benign_change);CHKERRQ(ierr); 407339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 408339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 409339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 4104f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 4114f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 4124f1b2e48SStefano Zampini PetscInt nzs,j; 4134f1b2e48SStefano Zampini 4144f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 4154f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 4164f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 4174f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 4184f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 4194f1b2e48SStefano Zampini } 420339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 421339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 422339f8db1SStefano Zampini /* set identity on velocities */ 423339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 424339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 425339f8db1SStefano Zampini } 4264f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 4274f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 428*9f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 4294f1b2e48SStefano 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); 430339f8db1SStefano Zampini /* set change on pressures */ 4314f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 4324f1b2e48SStefano Zampini PetscScalar *array; 4334f1b2e48SStefano Zampini PetscInt nzs; 4344f1b2e48SStefano Zampini 4354f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 4364f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 4374f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 438339f8db1SStefano Zampini PetscScalar vals[2]; 439339f8db1SStefano Zampini PetscInt cols[2]; 440339f8db1SStefano Zampini 441339f8db1SStefano Zampini cols[0] = idxs[i]; 4424f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 443339f8db1SStefano Zampini vals[0] = 1.; 444b0f5fe93SStefano Zampini vals[1] = 1.; 4454f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 446339f8db1SStefano Zampini } 4474f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 4484f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 4494f1b2e48SStefano Zampini array[nzs-1] = 1.; 4504f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 4514f1b2e48SStefano Zampini /* store local idxs for p0 */ 4524f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 4534f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 4544f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag_subs[s]);CHKERRQ(ierr); 455339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 4564f1b2e48SStefano Zampini } 457339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 458339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 459339f8db1SStefano Zampini /* TODO: need optimization? */ 460339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4611cf9b237SStefano Zampini ierr = MatPtAP(pcbddc->benign_original_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 4621cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 4631cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4644f1b2e48SStefano Zampini /* store global idxs for p0 */ 4654f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 466339f8db1SStefano Zampini } 4674f1b2e48SStefano Zampini ierr = PetscFree(zerodiag_subs);CHKERRQ(ierr); 4684f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 469b0f5fe93SStefano Zampini 470b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 471b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 472339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 473339f8db1SStefano Zampini PetscFunctionReturn(0); 474339f8db1SStefano Zampini } 475339f8db1SStefano Zampini 476339f8db1SStefano Zampini #undef __FUNCT__ 477015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 478015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 479efc2fbd9SStefano Zampini { 480efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 481efc2fbd9SStefano Zampini PetscErrorCode ierr; 482efc2fbd9SStefano Zampini 483efc2fbd9SStefano Zampini PetscFunctionBegin; 484efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 485efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 4864f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 487efc2fbd9SStefano Zampini } 488015636ebSStefano Zampini if (get) { /* use SF to get values */ 489efc2fbd9SStefano Zampini PetscScalar *array; 490efc2fbd9SStefano Zampini 491efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 4924f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 4934f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 494efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 4954f1b2e48SStefano Zampini } else { /* use VecSetValues (not scalable, I should try to find a better solution (defining a new MPI_OP for reduction) */ 4964f1b2e48SStefano Zampini ierr = VecSetValues(v,pcbddc->benign_n,pcbddc->benign_p0_gidx,pcbddc->benign_p0,INSERT_VALUES);CHKERRQ(ierr); 497efc2fbd9SStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 498efc2fbd9SStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 499efc2fbd9SStefano Zampini } 500efc2fbd9SStefano Zampini PetscFunctionReturn(0); 501efc2fbd9SStefano Zampini } 502efc2fbd9SStefano Zampini 503efc2fbd9SStefano Zampini #undef __FUNCT__ 504c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 505c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 506c263805aSStefano Zampini { 507c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 508c263805aSStefano Zampini PetscErrorCode ierr; 509c263805aSStefano Zampini 510c263805aSStefano Zampini PetscFunctionBegin; 511c263805aSStefano Zampini /* TODO: add error checking 512c263805aSStefano Zampini - avoid nested pop (or push) calls. 513c263805aSStefano Zampini - cannot push before pop. 5141c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 515c263805aSStefano Zampini */ 5164f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 517efc2fbd9SStefano Zampini PetscFunctionReturn(0); 518efc2fbd9SStefano Zampini } 519c263805aSStefano Zampini if (pop) { 5204f1b2e48SStefano Zampini IS is_p0; 5214f1b2e48SStefano Zampini MatReuse reuse; 522c263805aSStefano Zampini 523c263805aSStefano Zampini /* extract B_0 */ 5244f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 5254f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 5264f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 5274f1b2e48SStefano Zampini } 5284f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 5294f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 530c263805aSStefano Zampini /* remove rows and cols from local problem */ 531c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 5324f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 5334f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 534c263805aSStefano Zampini } else { /* push */ 5354f1b2e48SStefano Zampini PetscInt i; 5364f1b2e48SStefano Zampini 5374f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 5384f1b2e48SStefano Zampini PetscScalar *B0_vals; 5394f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 5404f1b2e48SStefano Zampini 5414f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 5424f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 5434f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+1,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 5444f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 5454f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 5464f1b2e48SStefano Zampini } 547c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 548c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 549c263805aSStefano Zampini } 550c263805aSStefano Zampini PetscFunctionReturn(0); 551c263805aSStefano Zampini } 552c263805aSStefano Zampini 553c263805aSStefano Zampini #undef __FUNCT__ 554b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 55508122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 556b1b3d7a2SStefano Zampini { 557b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 55808122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 55908122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 56008122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 56108122e43SStefano Zampini PetscScalar *work,lwork; 56208122e43SStefano Zampini PetscScalar *St,*S,*eigv; 56308122e43SStefano Zampini PetscScalar *Sarray,*Starray; 56408122e43SStefano Zampini PetscReal *eigs,thresh; 5651b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 566f6f667cfSStefano Zampini PetscBool allocated_S_St; 56708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 56808122e43SStefano Zampini PetscReal *rwork; 56908122e43SStefano Zampini #endif 570b1b3d7a2SStefano Zampini PetscErrorCode ierr; 571b1b3d7a2SStefano Zampini 572b1b3d7a2SStefano Zampini PetscFunctionBegin; 57308122e43SStefano Zampini if (!sub_schurs->use_mumps) { 57408122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS"); 57508122e43SStefano Zampini } 57608122e43SStefano Zampini 57706a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 57806a4e24aSStefano 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); 57906a4e24aSStefano Zampini } 58006a4e24aSStefano Zampini 581fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 582fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 583fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 584fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 585fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 586fd14bc51SStefano Zampini } 587fd14bc51SStefano Zampini 588e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 589e496cd5dSStefano 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); 590e496cd5dSStefano Zampini } 591e496cd5dSStefano Zampini 59208122e43SStefano Zampini /* max size of subsets */ 59308122e43SStefano Zampini mss = 0; 59408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 59508122e43SStefano Zampini PetscInt subset_size; 596862806e4SStefano Zampini 59708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 59808122e43SStefano Zampini mss = PetscMax(mss,subset_size); 59908122e43SStefano Zampini } 60008122e43SStefano Zampini 60108122e43SStefano Zampini /* min/max and threshold */ 60208122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 603f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 60408122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 605f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 606f6f667cfSStefano Zampini if (nmin) { 607f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 608f6f667cfSStefano Zampini } 60908122e43SStefano Zampini 61008122e43SStefano Zampini /* allocate lapack workspace */ 61108122e43SStefano Zampini cum = cum2 = 0; 61208122e43SStefano Zampini maxneigs = 0; 61308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 61408122e43SStefano Zampini PetscInt n,subset_size; 615f6f667cfSStefano Zampini 61608122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 61708122e43SStefano Zampini n = PetscMin(subset_size,nmax); 6189162d606SStefano Zampini cum += subset_size; 6199162d606SStefano Zampini cum2 += subset_size*n; 62008122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 62108122e43SStefano Zampini } 62208122e43SStefano Zampini if (mss) { 6239ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 62408122e43SStefano Zampini PetscBLASInt B_itype = 1; 62508122e43SStefano Zampini PetscBLASInt B_N = mss; 6264c6709b3SStefano Zampini PetscReal zero = 0.0; 6274c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 62808122e43SStefano Zampini 62908122e43SStefano Zampini B_lwork = -1; 63008122e43SStefano Zampini S = NULL; 63108122e43SStefano Zampini St = NULL; 632a58a30b4SStefano Zampini eigs = NULL; 633a58a30b4SStefano Zampini eigv = NULL; 634a58a30b4SStefano Zampini B_iwork = NULL; 635a58a30b4SStefano Zampini B_ifail = NULL; 636d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 637d1710679SStefano Zampini rwork = NULL; 638d1710679SStefano Zampini #endif 6398bec7fa6SStefano Zampini thresh = 1.0; 64008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 64108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 64208122e43SStefano 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)); 64308122e43SStefano Zampini #else 64408122e43SStefano 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)); 64508122e43SStefano Zampini #endif 64608122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 64708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 64808122e43SStefano Zampini } else { 64908122e43SStefano Zampini /* TODO */ 65008122e43SStefano Zampini } 65108122e43SStefano Zampini } else { 65208122e43SStefano Zampini lwork = 0; 65308122e43SStefano Zampini } 65408122e43SStefano Zampini 65508122e43SStefano Zampini nv = 0; 656d62866d3SStefano 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) */ 657d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 65808122e43SStefano Zampini } 6594c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 660f6f667cfSStefano Zampini if (allocated_S_St) { 661f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 662f6f667cfSStefano Zampini } 663f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 66408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 66508122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 66608122e43SStefano Zampini #endif 6679162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 6689162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 6699162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 67008122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 6719162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 67208122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 67308122e43SStefano Zampini 67408122e43SStefano Zampini maxneigs = 0; 67508122e43SStefano Zampini cum = cum2 = cumarray = 0; 6769162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 6779162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 678d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 67908122e43SStefano Zampini const PetscInt *idxs; 68008122e43SStefano Zampini 681d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 68208122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 68308122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 68408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 68508122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 6869162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 6879162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 68808122e43SStefano Zampini } 68908122e43SStefano Zampini cum2 = cum; 690d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 69108122e43SStefano Zampini } 69208122e43SStefano Zampini 69308122e43SStefano Zampini if (mss) { /* multilevel */ 69408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 69508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 69608122e43SStefano Zampini } 69708122e43SStefano Zampini 69808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 69908122e43SStefano Zampini 70008122e43SStefano Zampini const PetscInt *idxs; 701f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 702862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 70308122e43SStefano Zampini PetscBLASInt B_N; 704aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 70508122e43SStefano Zampini 706862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 707f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 708f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 7099ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 710aff50787SStefano Zampini PetscInt j,k; 711aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 712aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 713aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 71408122e43SStefano Zampini } 71508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 716aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 717aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 718aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 719aff50787SStefano Zampini } 72008122e43SStefano Zampini } 72108122e43SStefano Zampini } else { 72208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 72308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 72408122e43SStefano Zampini } 7258bec7fa6SStefano Zampini } else { 726f6f667cfSStefano Zampini S = Sarray + cumarray; 727f6f667cfSStefano Zampini St = Starray + cumarray; 7288bec7fa6SStefano Zampini } 72908122e43SStefano Zampini 730f6f667cfSStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 731aff50787SStefano Zampini /* see if we can save some work */ 732aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 733aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 734aff50787SStefano Zampini } 735aff50787SStefano Zampini 736aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 737aff50787SStefano Zampini B_neigs = 0; 738aff50787SStefano Zampini } else { 739aff50787SStefano Zampini /* Threshold: this is an heuristic for edges */ 740f6f667cfSStefano Zampini thresh = pcbddc->mat_graph->count[idxs[0]]*pcbddc->adaptive_threshold; 7411cf9b237SStefano Zampini if (nmin) { 7421cf9b237SStefano Zampini Mat SM,StM; 7431cf9b237SStefano Zampini PetscInt j,k,nccs,nccst; 7441cf9b237SStefano Zampini 7451cf9b237SStefano Zampini for (j=0;j<subset_size;j++) { 7461cf9b237SStefano Zampini for (k=j;k<subset_size;k++) { 7471cf9b237SStefano Zampini S [k*subset_size+j] = S [j*subset_size+k]; 7481cf9b237SStefano Zampini St[k*subset_size+j] = St[j*subset_size+k]; 7491cf9b237SStefano Zampini } 7501cf9b237SStefano Zampini } 7511cf9b237SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,S,&SM);CHKERRQ(ierr); 7521cf9b237SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,St,&StM);CHKERRQ(ierr); 7531cf9b237SStefano Zampini ierr = MatDetectDisconnectedComponents(SM,PETSC_TRUE,&nccs,NULL);CHKERRQ(ierr); 7541cf9b237SStefano Zampini ierr = MatDetectDisconnectedComponents(StM,PETSC_TRUE,&nccst,NULL);CHKERRQ(ierr); 7551cf9b237SStefano Zampini if (nccs != 1 || nccst != 1) { 7561cf9b237SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] Found disc %d %d (size %d)\n",PetscGlobalRank,nccs,nccst,subset_size); 7571cf9b237SStefano Zampini } 7581cf9b237SStefano Zampini ierr = MatDestroy(&SM);CHKERRQ(ierr); 7591cf9b237SStefano Zampini ierr = MatDestroy(&StM);CHKERRQ(ierr); 7601cf9b237SStefano Zampini } 761f6f667cfSStefano Zampini 7629ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 76308122e43SStefano Zampini PetscBLASInt B_itype = 1; 764f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 7654c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 7669552c7c7SStefano Zampini PetscInt nmin_s; 76708122e43SStefano Zampini 768fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 7698bec7fa6SStefano 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]]); 770fd14bc51SStefano Zampini } 771d16cbb6bSStefano Zampini 77208122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 773d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 774d16cbb6bSStefano Zampini 775d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 77608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 777f6f667cfSStefano 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)); 77808122e43SStefano Zampini #else 779f6f667cfSStefano 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)); 78008122e43SStefano Zampini #endif 781d16cbb6bSStefano Zampini } else { 782d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 783d16cbb6bSStefano Zampini B_IL = 1; 784d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 785d16cbb6bSStefano 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)); 786d16cbb6bSStefano Zampini #else 787d16cbb6bSStefano 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)); 788d16cbb6bSStefano Zampini #endif 789d16cbb6bSStefano Zampini } 79008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 79108122e43SStefano Zampini if (B_ierr) { 79208122e43SStefano Zampini if (B_ierr < 0 ) { 79308122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 79408122e43SStefano Zampini } else if (B_ierr <= B_N) { 79508122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 79608122e43SStefano Zampini } else { 7979552c7c7SStefano 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); 79808122e43SStefano Zampini } 79908122e43SStefano Zampini } 80008122e43SStefano Zampini 80108122e43SStefano Zampini if (B_neigs > nmax) { 802fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 803fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 804fd14bc51SStefano Zampini } 805f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 80608122e43SStefano Zampini B_neigs = nmax; 80708122e43SStefano Zampini } 80808122e43SStefano Zampini 8099552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 8109552c7c7SStefano Zampini if (B_neigs < nmin_s) { 81108122e43SStefano Zampini PetscBLASInt B_neigs2; 81208122e43SStefano Zampini 813f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 814f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 815fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 816fd14bc51SStefano 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); 817fd14bc51SStefano Zampini } 8189ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 81908122e43SStefano Zampini PetscInt j; 82008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 82108122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 82208122e43SStefano Zampini } 82308122e43SStefano Zampini for (j=0;j<subset_size;j++) { 82408122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 82508122e43SStefano Zampini } 82608122e43SStefano Zampini } else { 82708122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 82808122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 82908122e43SStefano Zampini } 83008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 83108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 832f6f667cfSStefano 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)); 83308122e43SStefano Zampini #else 834f6f667cfSStefano 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)); 83508122e43SStefano Zampini #endif 83608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 83708122e43SStefano Zampini B_neigs += B_neigs2; 83808122e43SStefano Zampini } 83908122e43SStefano Zampini if (B_ierr) { 84008122e43SStefano Zampini if (B_ierr < 0 ) { 84108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 84208122e43SStefano Zampini } else if (B_ierr <= B_N) { 84308122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 84408122e43SStefano Zampini } else { 8459552c7c7SStefano 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); 84608122e43SStefano Zampini } 84708122e43SStefano Zampini } 848fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 849ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 85008122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 85108122e43SStefano Zampini if (eigs[j] == 0.0) { 852ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 85308122e43SStefano Zampini } else { 854ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 855fd14bc51SStefano Zampini } 85608122e43SStefano Zampini } 85708122e43SStefano Zampini } 85808122e43SStefano Zampini } else { 85908122e43SStefano Zampini /* TODO */ 86008122e43SStefano Zampini } 861aff50787SStefano Zampini } 8628bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 8638bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 8649162d606SStefano Zampini if (B_neigs) { 8659162d606SStefano 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); 866fd14bc51SStefano Zampini 867fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 8689552c7c7SStefano Zampini PetscInt ii; 8699552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 870ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 8719552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 872ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 873ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 874ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 875ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 876ac47001eSStefano Zampini #else 877ac47001eSStefano 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); 878ac47001eSStefano Zampini #endif 8799552c7c7SStefano Zampini } 8809552c7c7SStefano Zampini } 881fd14bc51SStefano Zampini } 88208122e43SStefano Zampini #if 0 8839162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 88408122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 88508122e43SStefano Zampini PetscScalar norm; 88608122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 8879162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 8889162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 88908122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 89008122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 89108122e43SStefano Zampini } else { 89208122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 89308122e43SStefano Zampini } 8949162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 895b1b3d7a2SStefano Zampini } 896b1b3d7a2SStefano Zampini #endif 8979162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 8989162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 8999162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 9009162d606SStefano Zampini cum++; 90108122e43SStefano Zampini } 90208122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 90308122e43SStefano Zampini /* shift for next computation */ 90408122e43SStefano Zampini cumarray += subset_size*subset_size; 90508122e43SStefano Zampini } 906fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 907fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 908fd14bc51SStefano Zampini } 90908122e43SStefano Zampini 91008122e43SStefano Zampini if (mss) { 91108122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 91208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 913f6f667cfSStefano Zampini /* destroy matrices (junk) */ 914f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 915f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 91608122e43SStefano Zampini } 917f6f667cfSStefano Zampini if (allocated_S_St) { 918f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 919f6f667cfSStefano Zampini } 920f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 92108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 92208122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 92308122e43SStefano Zampini #endif 92408122e43SStefano Zampini if (pcbddc->dbg_flag) { 9251b968477SStefano Zampini PetscInt maxneigs_r; 92608122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 9279b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 92808122e43SStefano Zampini } 92908122e43SStefano Zampini PetscFunctionReturn(0); 93008122e43SStefano Zampini } 931b1b3d7a2SStefano Zampini 932674ae819SStefano Zampini #undef __FUNCT__ 933c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 934c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 935c8587f34SStefano Zampini { 936c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 9378629588bSStefano Zampini PetscScalar *coarse_submat_vals; 938c8587f34SStefano Zampini PetscErrorCode ierr; 939c8587f34SStefano Zampini 940c8587f34SStefano Zampini PetscFunctionBegin; 941f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 9425e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 943c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 944c8587f34SStefano Zampini 945684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 9460fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 947684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 948c8587f34SStefano Zampini 949c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 950b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 951c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 952c8587f34SStefano Zampini } 953c8587f34SStefano Zampini 9548629588bSStefano Zampini /* 9558629588bSStefano Zampini Setup local correction and local part of coarse basis. 9568629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 9578629588bSStefano Zampini */ 95847f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 9598629588bSStefano Zampini 9608629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 9618629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 9628629588bSStefano Zampini 9638629588bSStefano Zampini /* free */ 9648629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 965c8587f34SStefano Zampini PetscFunctionReturn(0); 966c8587f34SStefano Zampini } 967c8587f34SStefano Zampini 968c8587f34SStefano Zampini #undef __FUNCT__ 969674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 970674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 971674ae819SStefano Zampini { 972674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 973674ae819SStefano Zampini PetscErrorCode ierr; 974674ae819SStefano Zampini 975674ae819SStefano Zampini PetscFunctionBegin; 976674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 977674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 978674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 979674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 980785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 981674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 982f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 983f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 984785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 98563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 98663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 987674ae819SStefano Zampini PetscFunctionReturn(0); 988674ae819SStefano Zampini } 989674ae819SStefano Zampini 990674ae819SStefano Zampini #undef __FUNCT__ 991674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 992674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 993674ae819SStefano Zampini { 994674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9954f1b2e48SStefano Zampini PetscInt i; 996674ae819SStefano Zampini PetscErrorCode ierr; 997674ae819SStefano Zampini 998674ae819SStefano Zampini PetscFunctionBegin; 999b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1000674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 1001674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1002674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 10034f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 10044f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 10054f1b2e48SStefano Zampini } 10064f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1007b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1008674ae819SStefano Zampini PetscFunctionReturn(0); 1009674ae819SStefano Zampini } 1010674ae819SStefano Zampini 1011674ae819SStefano Zampini #undef __FUNCT__ 1012674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1013674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1014674ae819SStefano Zampini { 1015674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 101606656605SStefano Zampini PetscScalar *array; 1017674ae819SStefano Zampini PetscErrorCode ierr; 1018674ae819SStefano Zampini 1019674ae819SStefano Zampini PetscFunctionBegin; 1020674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 102158da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 102206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 102306656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 102458da7f69SStefano Zampini } 1025674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1026674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 102715aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 102815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1029674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1030674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1031674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 103206656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1033674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1034674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10358ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1036674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1037674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1038674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1039f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1040f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1041f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1042f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1043727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 10440e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1045f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 104670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 10476e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 104881d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 10490369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 10508b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10514f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10524f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 10538b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 10544f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1055674ae819SStefano Zampini PetscFunctionReturn(0); 1056674ae819SStefano Zampini } 1057674ae819SStefano Zampini 1058674ae819SStefano Zampini #undef __FUNCT__ 1059f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1060f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 10616bfb1811SStefano Zampini { 10626bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10636bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 10646bfb1811SStefano Zampini VecType impVecType; 10654f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 10666bfb1811SStefano Zampini PetscErrorCode ierr; 10676bfb1811SStefano Zampini 10686bfb1811SStefano Zampini PetscFunctionBegin; 1069f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 1070019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1071f4ddd8eeSStefano Zampini } 1072e7b262bdSStefano Zampini /* get sizes */ 10734f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1074b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 10756bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1076e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1077e7b262bdSStefano Zampini /* R nodes */ 1078e7b262bdSStefano Zampini old_size = -1; 1079e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1080e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1081e7b262bdSStefano Zampini } 1082e7b262bdSStefano Zampini if (n_R != old_size) { 1083e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1084e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10856bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 10866bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 10876bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 10886bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1089e7b262bdSStefano Zampini } 1090e7b262bdSStefano Zampini /* local primal dofs */ 1091e7b262bdSStefano Zampini old_size = -1; 1092e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1093e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1094e7b262bdSStefano Zampini } 1095e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1096e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 109783b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1098e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 10996bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1100e7b262bdSStefano Zampini } 1101e7b262bdSStefano Zampini /* local explicit constraints */ 1102e7b262bdSStefano Zampini old_size = -1; 1103e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1104e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1105e7b262bdSStefano Zampini } 1106e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1107e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 110883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 110983b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 111083b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 111183b7ccabSStefano Zampini } 11126bfb1811SStefano Zampini PetscFunctionReturn(0); 11136bfb1811SStefano Zampini } 11146bfb1811SStefano Zampini 11156bfb1811SStefano Zampini #undef __FUNCT__ 111647f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 111747f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 111888ebb749SStefano Zampini { 111925084f0cSStefano Zampini PetscErrorCode ierr; 112025084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 112188ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 112288ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1123d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 112425084f0cSStefano Zampini /* submatrices of local problem */ 112580677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 1126019a44ceSStefano Zampini /* submatrices of benign trick */ 1127d16cbb6bSStefano Zampini Mat B0_V = NULL; 112806656605SStefano Zampini /* submatrices of local coarse problem */ 112906656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 113025084f0cSStefano Zampini /* working matrices */ 113106656605SStefano Zampini Mat C_CR; 113225084f0cSStefano Zampini /* additional working stuff */ 113306656605SStefano Zampini PC pc_R; 11344f1b2e48SStefano Zampini Mat F; 113506656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 113606656605SStefano Zampini 113725084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 113806656605SStefano Zampini PetscScalar *work; 113906656605SStefano Zampini PetscInt *idx_V_B; 11404f1b2e48SStefano Zampini PetscInt n,n_vertices,n_constraints,*p0_lidx_I; 114106656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1142b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 114345a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 114488ebb749SStefano Zampini MatType impMatType; 114525084f0cSStefano Zampini /* some shortcuts to scalars */ 114606656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 114788ebb749SStefano Zampini 114888ebb749SStefano Zampini PetscFunctionBegin; 1149b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 11504f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 115188ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 1152b371cd4fSStefano Zampini n_B = pcis->n_B; 1153b371cd4fSStefano Zampini n_D = pcis->n - n_B; 115488ebb749SStefano Zampini n_R = pcis->n - n_vertices; 115588ebb749SStefano Zampini 115688ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 115788ebb749SStefano Zampini impMatType = MATSEQDENSE; 115888ebb749SStefano Zampini 115988ebb749SStefano Zampini /* vertices in boundary numbering */ 1160785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 11610e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 116288ebb749SStefano Zampini if (i != n_vertices) { 116322d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 116488ebb749SStefano Zampini } 116588ebb749SStefano Zampini 116606656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1167019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 116806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 116906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 117006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 117106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 117206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 117306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 117406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 117506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 117606656605SStefano Zampini 117706656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 117806656605SStefano Zampini /* allocate workspace */ 117906656605SStefano Zampini n = 0; 118006656605SStefano Zampini if (n_constraints) { 118106656605SStefano Zampini n += n_R*n_constraints; 118206656605SStefano Zampini } 118306656605SStefano Zampini if (n_vertices) { 118406656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 118580677318SStefano Zampini n = PetscMax((n_R+n_B)*n_vertices,n); 118606656605SStefano Zampini } 11873301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 118806656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 118906656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 119006656605SStefano Zampini } 119106656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 119206656605SStefano Zampini 119306656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 119406656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 119506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 119606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 119706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 119806656605SStefano Zampini if (isLU || isILU || isCHOL) { 119906656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1200d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 1201d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1202d62866d3SStefano Zampini MatFactorType type; 1203d62866d3SStefano Zampini 12046816873aSStefano Zampini F = reuse_mumps->F; 12056816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1206d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 120706656605SStefano Zampini } else { 120806656605SStefano Zampini F = NULL; 120906656605SStefano Zampini } 121006656605SStefano Zampini 121188ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 121288ebb749SStefano Zampini if (n_constraints) { 121306656605SStefano Zampini Mat M1,M2,M3; 121480677318SStefano Zampini Mat auxmat; 121506656605SStefano Zampini IS is_aux; 121680677318SStefano Zampini PetscScalar *array,*array2; 121706656605SStefano Zampini 1218f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 121980677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 122088ebb749SStefano Zampini 122125084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 122225084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 12238ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 122480677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 122588ebb749SStefano Zampini 122680677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 122780677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 122806656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 122988ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 123006656605SStefano Zampini const PetscScalar *row_cmat_values; 123106656605SStefano Zampini const PetscInt *row_cmat_indices; 123206656605SStefano Zampini PetscInt size_of_constraint,j; 123388ebb749SStefano Zampini 123406656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 123506656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 123606656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 123706656605SStefano Zampini } 123806656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 123906656605SStefano Zampini } 124080677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 124106656605SStefano Zampini if (F) { 124206656605SStefano Zampini Mat B; 124306656605SStefano Zampini 124406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 124580677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 124606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 124706656605SStefano Zampini } else { 124880677318SStefano Zampini PetscScalar *marr; 124980677318SStefano Zampini 125080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 125106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 125206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 125380677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*n_R);CHKERRQ(ierr); 125406656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 125506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 125606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 125706656605SStefano Zampini } 125880677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 125906656605SStefano Zampini } 126080677318SStefano Zampini if (!pcbddc->switch_static) { 126180677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 126280677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 126380677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 126480677318SStefano Zampini for (i=0;i<n_constraints;i++) { 126580677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*n_R);CHKERRQ(ierr); 126680677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 126780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126980677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 127080677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 127180677318SStefano Zampini } 127280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 127380677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 127480677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 127580677318SStefano Zampini } else { 127680677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 127780677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 127825084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 127980677318SStefano Zampini } 128080677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 128180677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 128280677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 128306656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 128406656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 128580677318SStefano Zampini if (isCHOL) { 128680677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 128780677318SStefano Zampini } else { 128825084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 128980677318SStefano Zampini } 129080677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 129106656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 129225084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 129325084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 129425084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 129580677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 129680677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 129780677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 129806656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 129906656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1300f4ddd8eeSStefano Zampini } 130188ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 13024f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1303d16cbb6bSStefano Zampini IS dummy; 1304d16cbb6bSStefano Zampini Mat B0_R; 1305d16cbb6bSStefano Zampini PetscReal norm; 1306d16cbb6bSStefano Zampini 13074f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13084f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1309d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1310d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1311d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1312d16cbb6bSStefano Zampini } 1313d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1314d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1315d16cbb6bSStefano Zampini } 1316d16cbb6bSStefano Zampini 131788ebb749SStefano Zampini if (n_vertices) { 131806656605SStefano Zampini IS is_aux; 13193a50541eSStefano Zampini 13206816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 13216816873aSStefano Zampini IS tis; 13226816873aSStefano Zampini 13236816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 13246816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 13256816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 13266816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 13276816873aSStefano Zampini } else { 13283a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 13296816873aSStefano Zampini } 13309577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 13319577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 133204708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 13334f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1334019a44ceSStefano Zampini IS dummy; 1335019a44ceSStefano Zampini 13364f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13374f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1338019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1339019a44ceSStefano Zampini } 134025084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 134188ebb749SStefano Zampini } 134288ebb749SStefano Zampini 134388ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1344f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 134506656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 134606656605SStefano Zampini if (pcbddc->coarse_phi_D) { 134706656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 134806656605SStefano Zampini } 1349f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 135006656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 135106656605SStefano Zampini PetscScalar *marray; 135206656605SStefano Zampini 135306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 135406656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1355f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1356f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1357f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1358f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1359f4ddd8eeSStefano Zampini } 1360f4ddd8eeSStefano Zampini } 136106656605SStefano Zampini 1362f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 136306656605SStefano Zampini PetscScalar *marray; 136488ebb749SStefano Zampini 136506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13668eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 136706656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 136888ebb749SStefano Zampini } 13693301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 137006656605SStefano Zampini n *= 2; 137188ebb749SStefano Zampini } 137206656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 137306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 137406656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13758eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 137606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 137706656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 137888ebb749SStefano Zampini } 13793301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 138006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 13818eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 138206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 138306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 138488ebb749SStefano Zampini } 138588ebb749SStefano Zampini } else { 1386c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1387c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 13881b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1389c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1390c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1391c0553b1fSStefano Zampini } 139288ebb749SStefano Zampini } 139306656605SStefano Zampini } 1394019a44ceSStefano Zampini 139506656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 13964f1b2e48SStefano Zampini p0_lidx_I = NULL; 13974f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1398d12edf2fSStefano Zampini const PetscInt *idxs; 1399d12edf2fSStefano Zampini 1400d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 14014f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 14024f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 14034f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 14044f1b2e48SStefano Zampini } 1405d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1406d12edf2fSStefano Zampini } 1407d16cbb6bSStefano Zampini 140806656605SStefano Zampini /* vertices */ 140906656605SStefano Zampini if (n_vertices) { 141016f15bc4SStefano Zampini 141104708bb6SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 141204708bb6SStefano Zampini 141316f15bc4SStefano Zampini if (n_R) { 141406656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 141506656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 141616f15bc4SStefano Zampini PetscScalar *x,*y; 141704708bb6SStefano Zampini PetscBool isseqaij; 141806656605SStefano Zampini 141921eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 142006656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 142104708bb6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 14226816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 142306656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 142406656605SStefano Zampini } else { 142506656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 142606656605SStefano Zampini for (i=0;i<n_vertices;i++) { 142706656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 142806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 142906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 143006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 143106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 143206656605SStefano Zampini } 143306656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 143406656605SStefano Zampini } 143580677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 143606656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 143706656605SStefano Zampini if (n_constraints) { 143806656605SStefano Zampini Mat B; 143980677318SStefano Zampini 1440b3d85658SStefano Zampini ierr = PetscMemzero(work+n_R*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 144180677318SStefano Zampini for (i=0;i<n_vertices;i++) { 144280677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 144380677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+n_R*n_vertices+i*n_B);CHKERRQ(ierr); 144480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 144580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 144680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 144780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 144880677318SStefano Zampini } 144980677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 145080677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 145180677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 145206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 145380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 145406656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 145506656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 145606656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 145706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 145806656605SStefano Zampini } 145904708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 146004708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 146104708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 146204708bb6SStefano Zampini } 146306656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 146480677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 146506656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 146606656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 146706656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 146806656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 146906656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 147006656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 147106656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1472d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1473019a44ceSStefano Zampini } else { 1474d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1475d16cbb6bSStefano Zampini } 14764f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1477019a44ceSStefano Zampini const PetscScalar *vals; 1478019a44ceSStefano Zampini const PetscInt *idxs; 14794f1b2e48SStefano Zampini PetscInt n,j,primal_idx; 1480019a44ceSStefano Zampini 14814f1b2e48SStefano Zampini ierr = MatGetRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 14824f1b2e48SStefano Zampini primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + i; 1483d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 14844f1b2e48SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+idxs[j]] = vals[j]; 14854f1b2e48SStefano Zampini coarse_submat_vals[idxs[j]*pcbddc->local_primal_size+primal_idx] = vals[j]; 1486019a44ceSStefano Zampini } 14874f1b2e48SStefano Zampini ierr = MatRestoreRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 148816f15bc4SStefano Zampini } 148921eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1490d16cbb6bSStefano Zampini 149106656605SStefano Zampini /* coarse basis functions */ 149206656605SStefano Zampini for (i=0;i<n_vertices;i++) { 149316f15bc4SStefano Zampini PetscScalar *y; 149416f15bc4SStefano Zampini 149506656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 149606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 149706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 149806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 149906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 150006656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 150106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 150206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 150306656605SStefano Zampini 150406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15054f1b2e48SStefano Zampini PetscInt j; 15064f1b2e48SStefano Zampini 150706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 150806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 150906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 151006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 151106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15124f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 151306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 151406656605SStefano Zampini } 151506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 151606656605SStefano Zampini } 151704708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 151804708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 151906656605SStefano Zampini } 152006656605SStefano Zampini 152106656605SStefano Zampini if (n_constraints) { 152206656605SStefano Zampini Mat B; 152306656605SStefano Zampini 152406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 152506656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 152680677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 152706656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 152806656605SStefano Zampini if (n_vertices) { 152980677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 153080677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 153180677318SStefano Zampini } else { 153280677318SStefano Zampini Mat S_VCt; 153380677318SStefano Zampini 153480677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 153580677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 153680677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 153780677318SStefano Zampini } 153806656605SStefano Zampini } 153906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 154006656605SStefano Zampini /* coarse basis functions */ 154106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 154206656605SStefano Zampini PetscScalar *y; 154306656605SStefano Zampini 154406656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 154506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 154606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 154706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 154806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 154906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 155006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 155106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15524f1b2e48SStefano Zampini PetscInt j; 15534f1b2e48SStefano Zampini 155406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 155506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 155606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15594f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 156006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 156106656605SStefano Zampini } 156206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 156306656605SStefano Zampini } 156406656605SStefano Zampini } 156580677318SStefano Zampini if (n_constraints) { 156680677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 156780677318SStefano Zampini } 15684f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 1569019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1570019a44ceSStefano Zampini 157106656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 15723301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 157306656605SStefano Zampini 157406656605SStefano Zampini if (n_constraints) { 157516f15bc4SStefano Zampini Mat S_CCT,B_C; 157606656605SStefano Zampini 157780677318SStefano Zampini /* this is a lazy thing */ 157880677318SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 157906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 158006656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 158106656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 158216f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 158306656605SStefano Zampini if (n_vertices) { 158416f15bc4SStefano Zampini Mat B_V,S_VCT; 158506656605SStefano Zampini 158606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 158706656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 158806656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 158906656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 159016f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 159106656605SStefano Zampini } 159206656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 159380677318SStefano Zampini } else { /* if there are no constraints, reset work */ 159480677318SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 159506656605SStefano Zampini } 159616f15bc4SStefano Zampini if (n_vertices && n_R) { 159706656605SStefano Zampini Mat A_VRT; 159880677318SStefano Zampini PetscScalar *marray; 159906656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 160006656605SStefano Zampini 160180677318SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_VRT);CHKERRQ(ierr); 160280677318SStefano Zampini ierr = MatConvert(A_VRT,impMatType,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 160380677318SStefano Zampini ierr = MatDenseGetArray(A_VRT,&marray);CHKERRQ(ierr); 160406656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 160580677318SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,marray,&B_one,work,&B_one)); 160680677318SStefano Zampini ierr = MatDenseRestoreArray(A_VRT,&marray);CHKERRQ(ierr); 160716f15bc4SStefano Zampini ierr = MatDestroy(&A_VRT);CHKERRQ(ierr); 160806656605SStefano Zampini } 160906656605SStefano Zampini 161006656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 161106656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 161206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 161306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 161406656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 161506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 161606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 161706656605SStefano Zampini } 161806656605SStefano Zampini } else { 161906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 162006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 162106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 162206656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 162306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 162406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 162506656605SStefano Zampini } 162606656605SStefano Zampini } 162706656605SStefano Zampini /* coarse basis functions */ 162806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 162906656605SStefano Zampini PetscScalar *y; 163006656605SStefano Zampini 163106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 163206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 163306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 163406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 163506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 163606656605SStefano Zampini if (i<n_vertices) { 163706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 163806656605SStefano Zampini } 163906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 164006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 164106656605SStefano Zampini 164206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 164306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 164406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 164506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 164606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 164706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 164806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 164906656605SStefano Zampini } 165006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 165106656605SStefano Zampini } 165206656605SStefano Zampini } 1653d62866d3SStefano Zampini /* free memory */ 165488ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 165506656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 165606656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 165706656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 165806656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 1659d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1660d62866d3SStefano Zampini if (n_vertices) { 1661d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1662d62866d3SStefano Zampini } 1663d62866d3SStefano Zampini if (n_constraints) { 1664d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 1665d62866d3SStefano Zampini } 166688ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 166788ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 166888ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1669d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 167088ebb749SStefano Zampini Mat coarse_sub_mat; 167125084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 167288ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 167388ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 167488ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 16758bec7fa6SStefano Zampini Mat C_B,CPHI; 16768bec7fa6SStefano Zampini IS is_dummy; 16778bec7fa6SStefano Zampini Vec mones; 167888ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 167988ebb749SStefano Zampini PetscReal real_value; 168088ebb749SStefano Zampini 168188ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 168288ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 168388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 168488ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 168588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 168688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1687c0553b1fSStefano Zampini if (unsymmetric_check) { 168888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 168988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 169088ebb749SStefano Zampini } 169188ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 169288ebb749SStefano Zampini 169325084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 16943301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 169525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1696c0553b1fSStefano Zampini if (unsymmetric_check) { 169788ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 169888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 169988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170088ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 170288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 170588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 170888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170988ebb749SStefano Zampini } else { 171088ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 171188ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 171288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 171388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 171488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 171588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 171688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 171788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 171888ebb749SStefano Zampini } 171988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 172088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 172188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 172288ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 17234f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1724d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 1725d12edf2fSStefano Zampini PetscScalar *data,*data2; 17264f1b2e48SStefano Zampini PetscInt j; 1727d12edf2fSStefano Zampini 17284f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 17294f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 17304f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 1731d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 1732d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 1733d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 1734d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 17354f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 17364f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 1737d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 17384f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 17394f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 17404f1b2e48SStefano Zampini } 1741d12edf2fSStefano Zampini } 1742d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 1743d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 1744d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 1745d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 1746d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 1747d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 1748d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 1749d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1750d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 1751d12edf2fSStefano Zampini } 1752d12edf2fSStefano Zampini #if 0 1753d12edf2fSStefano Zampini { 1754d12edf2fSStefano Zampini PetscViewer viewer; 1755d12edf2fSStefano Zampini char filename[256]; 1756d12edf2fSStefano Zampini sprintf(filename,"proj_local_coarse_mat%d.m",PetscGlobalRank); 1757d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1758d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1759d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 1760d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1761d12edf2fSStefano Zampini } 1762d12edf2fSStefano Zampini #endif 176381d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 17648bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 17650fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 176606656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 17678bec7fa6SStefano Zampini 17688bec7fa6SStefano Zampini /* check constraints */ 17694f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 17708bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 17718bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 17728bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 17738bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 17748bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 17758bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 17768bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1777bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 1778c0553b1fSStefano Zampini if (unsymmetric_check) { 1779bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 1780bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 1781bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 1782bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1783bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 178488ebb749SStefano Zampini } 17858bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 17868bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 17878bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 17888bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 1789d12edf2fSStefano Zampini } 179025084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 179188ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 179288ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 179388ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 179488ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 179588ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 179688ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 179788ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 179888ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 179988ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 180088ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 1801c0553b1fSStefano Zampini if (unsymmetric_check) { 180288ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 180388ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 180488ebb749SStefano Zampini } 180588ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 180688ebb749SStefano Zampini } 18078629588bSStefano Zampini /* get back data */ 18088629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 180988ebb749SStefano Zampini PetscFunctionReturn(0); 181088ebb749SStefano Zampini } 181188ebb749SStefano Zampini 181288ebb749SStefano Zampini #undef __FUNCT__ 1813d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1814d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 1815aa0d41d4SStefano Zampini { 1816d65f70fdSStefano Zampini Mat *work_mat; 1817d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1818d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1819d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1820aa0d41d4SStefano Zampini PetscErrorCode ierr; 1821aa0d41d4SStefano Zampini 1822aa0d41d4SStefano Zampini PetscFunctionBegin; 1823d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1824d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1825d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1826d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1827aa0d41d4SStefano Zampini 1828d65f70fdSStefano Zampini if (!rsorted) { 1829906d46d4SStefano Zampini const PetscInt *idxs; 1830906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 1831aa0d41d4SStefano Zampini 1832d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1833d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1834d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1835d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1836aa0d41d4SStefano Zampini } 1837d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1838d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1839d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1840d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1841aa0d41d4SStefano Zampini } 1842d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1843d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1844d65f70fdSStefano Zampini } else { 1845d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1846d65f70fdSStefano Zampini isrow_s = isrow; 1847aa0d41d4SStefano Zampini } 1848906d46d4SStefano Zampini 1849d65f70fdSStefano Zampini if (!csorted) { 1850d65f70fdSStefano Zampini if (isrow == iscol) { 1851d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1852d65f70fdSStefano Zampini iscol_s = isrow_s; 1853d65f70fdSStefano Zampini } else { 1854d65f70fdSStefano Zampini const PetscInt *idxs; 1855d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1856906d46d4SStefano Zampini 1857d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1858d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1859d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1860d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1861d65f70fdSStefano Zampini } 1862d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1863d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1864d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1865d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1866d65f70fdSStefano Zampini } 1867d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1868d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1869d65f70fdSStefano Zampini } 1870d65f70fdSStefano Zampini } else { 1871d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1872d65f70fdSStefano Zampini iscol_s = iscol; 1873d65f70fdSStefano Zampini } 1874d65f70fdSStefano Zampini 1875d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1876d65f70fdSStefano Zampini 1877d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1878906d46d4SStefano Zampini Mat new_mat; 1879d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1880906d46d4SStefano Zampini 1881d65f70fdSStefano Zampini if (!rsorted) { 1882d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1883d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1884d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1885d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1886906d46d4SStefano Zampini } 1887d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1888d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1889d65f70fdSStefano Zampini } else { 1890d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1891906d46d4SStefano Zampini } 1892d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1893d65f70fdSStefano Zampini 1894d65f70fdSStefano Zampini if (!csorted) { 1895d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1896d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1897d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1898d65f70fdSStefano Zampini } else { 1899d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1900d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1901d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1902d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1903d65f70fdSStefano Zampini } 1904d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1905d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1906d65f70fdSStefano Zampini } 1907d65f70fdSStefano Zampini } else { 1908d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1909d65f70fdSStefano Zampini } 1910d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1911d65f70fdSStefano Zampini 1912d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1913d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1914d65f70fdSStefano Zampini work_mat[0] = new_mat; 1915d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1916d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1917d65f70fdSStefano Zampini } 1918d65f70fdSStefano Zampini 1919d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1920d65f70fdSStefano Zampini *B = work_mat[0]; 1921d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1922d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1923d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1924d65f70fdSStefano Zampini PetscFunctionReturn(0); 1925d65f70fdSStefano Zampini } 1926d65f70fdSStefano Zampini 1927d65f70fdSStefano Zampini #undef __FUNCT__ 19285e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 19295e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1930aa0d41d4SStefano Zampini { 1931aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 19325e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1933d65f70fdSStefano Zampini Mat new_mat; 19345e8657edSStefano Zampini IS is_local,is_global; 1935d65f70fdSStefano Zampini PetscInt local_size; 1936d65f70fdSStefano Zampini PetscBool isseqaij; 1937aa0d41d4SStefano Zampini PetscErrorCode ierr; 1938aa0d41d4SStefano Zampini 1939aa0d41d4SStefano Zampini PetscFunctionBegin; 1940aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 19415e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 19425e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1943b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 1944aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1945d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 1946aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1947906d46d4SStefano Zampini 1948906d46d4SStefano Zampini /* check */ 1949906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1950906d46d4SStefano Zampini Vec x,x_change; 1951906d46d4SStefano Zampini PetscReal error; 1952906d46d4SStefano Zampini 19535e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1954906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 19555e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 1956e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1957e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1958d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 1959e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1960e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1961906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1962906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1963906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1964906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1965906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1966906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1967906d46d4SStefano Zampini } 1968906d46d4SStefano Zampini 196922d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 19709b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 197122d5777bSStefano Zampini if (isseqaij) { 19721cf9b237SStefano Zampini Mat M; 19731cf9b237SStefano Zampini 19741cf9b237SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 19751cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 19761cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1977aa0d41d4SStefano Zampini } else { 19781cf9b237SStefano Zampini Mat work_mat,M; 19791cf9b237SStefano Zampini 1980aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 19811cf9b237SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 19821cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 19831cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1984aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1985aa0d41d4SStefano Zampini } 19863301b35fSStefano Zampini if (matis->A->symmetric_set) { 19873301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 1988e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 19893301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 1990e496cd5dSStefano Zampini #endif 19913301b35fSStefano Zampini } 199245a1bb75SStefano Zampini /* 199345a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1994d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 199545a1bb75SStefano Zampini */ 1996d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1997aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1998aa0d41d4SStefano Zampini } 1999aa0d41d4SStefano Zampini 2000aa0d41d4SStefano Zampini #undef __FUNCT__ 2001a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 20028ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2003a64d13efSStefano Zampini { 2004a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2005a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2006d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 200753892102SStefano Zampini PetscInt *idx_R_local=NULL; 20083a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 20093a50541eSStefano Zampini PetscInt vbs,bs; 20106816873aSStefano Zampini PetscBT bitmask=NULL; 2011a64d13efSStefano Zampini PetscErrorCode ierr; 2012a64d13efSStefano Zampini 2013a64d13efSStefano Zampini PetscFunctionBegin; 2014b23d619eSStefano Zampini /* 2015b23d619eSStefano Zampini No need to setup local scatters if 2016b23d619eSStefano Zampini - primal space is unchanged 2017b23d619eSStefano Zampini AND 2018b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2019b23d619eSStefano Zampini AND 2020b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2021b23d619eSStefano Zampini */ 2022b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2023f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2024f4ddd8eeSStefano Zampini } 2025f4ddd8eeSStefano Zampini /* destroy old objects */ 2026f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2027f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2028f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2029a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2030b371cd4fSStefano Zampini n_B = pcis->n_B; 2031b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2032b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 20333a50541eSStefano Zampini 2034a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 20356816873aSStefano Zampini 203653892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 20376816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 2038854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2039a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2040a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 20410e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2042a64d13efSStefano Zampini } 2043a64d13efSStefano Zampini 2044a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 20454641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 20466816873aSStefano Zampini idx_R_local[n_R++] = i; 2047a64d13efSStefano Zampini } 2048a64d13efSStefano Zampini } 204953892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 20506816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 20516816873aSStefano Zampini 205253892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 205353892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 20546816873aSStefano Zampini } 20553a50541eSStefano Zampini 20563a50541eSStefano Zampini /* Block code */ 20573a50541eSStefano Zampini vbs = 1; 20583a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 20593a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 20603a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 20613a50541eSStefano Zampini PetscInt *vary; 2062d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 2063785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 20643a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2065d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2066d3df7717SStefano 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 */ 20670e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2068d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 20693a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 20703a50541eSStefano Zampini is_blocked = PETSC_FALSE; 20713a50541eSStefano Zampini break; 20723a50541eSStefano Zampini } 20733a50541eSStefano Zampini } 2074d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2075d3df7717SStefano Zampini } else { 2076d3df7717SStefano Zampini /* Verify directly the R set */ 2077d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2078d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2079d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2080d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2081d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2082d3df7717SStefano Zampini break; 2083d3df7717SStefano Zampini } 2084d3df7717SStefano Zampini } 2085d3df7717SStefano Zampini } 2086d3df7717SStefano Zampini } 20873a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 20883a50541eSStefano Zampini vbs = bs; 20893a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 20903a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 20913a50541eSStefano Zampini } 20923a50541eSStefano Zampini } 20933a50541eSStefano Zampini } 20943a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 209553892102SStefano Zampini if (sub_schurs->reuse_mumps) { 209653892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 209753892102SStefano Zampini 209853892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 209953892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 210053892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 210153892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 210253892102SStefano Zampini } else { 21033a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 210453892102SStefano Zampini } 2105a64d13efSStefano Zampini 2106a64d13efSStefano Zampini /* print some info if requested */ 2107a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2108a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2109a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 21100fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2111a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2112a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 21134f1b2e48SStefano 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); 2114a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2115a64d13efSStefano Zampini } 2116a64d13efSStefano Zampini 2117a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 21186816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 21196816873aSStefano Zampini IS is_aux1,is_aux2; 21206816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 21216816873aSStefano Zampini 21223a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2123854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2124854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2125a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 21264641a718SStefano Zampini for (i=0; i<n_D; i++) { 21274641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 21284641a718SStefano Zampini } 2129a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2130a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 21314641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 21324641a718SStefano Zampini aux_array1[j++] = i; 2133a64d13efSStefano Zampini } 2134a64d13efSStefano Zampini } 2135a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2136a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2137a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 21384641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 21394641a718SStefano Zampini aux_array2[j++] = i; 2140a64d13efSStefano Zampini } 2141a64d13efSStefano Zampini } 2142a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2143a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2144a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2145a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2146a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2147a64d13efSStefano Zampini 21488eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2149785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2150a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 21514641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 21524641a718SStefano Zampini aux_array1[j++] = i; 2153a64d13efSStefano Zampini } 2154a64d13efSStefano Zampini } 2155a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2156a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2157a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2158a64d13efSStefano Zampini } 21594641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 21603a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2161d62866d3SStefano Zampini } else { 216253892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 21636816873aSStefano Zampini IS tis; 21646816873aSStefano Zampini PetscInt schur_size; 21656816873aSStefano Zampini 216653892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 21676816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 216853892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 21696816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 21706816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 21716816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 21726816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 21736816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2174d62866d3SStefano Zampini } 2175d62866d3SStefano Zampini } 2176a64d13efSStefano Zampini PetscFunctionReturn(0); 2177a64d13efSStefano Zampini } 2178a64d13efSStefano Zampini 2179304d26faSStefano Zampini 2180304d26faSStefano Zampini #undef __FUNCT__ 2181304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2182684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2183304d26faSStefano Zampini { 2184304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2185304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2186304d26faSStefano Zampini PC pc_temp; 2187304d26faSStefano Zampini Mat A_RR; 2188f4ddd8eeSStefano Zampini MatReuse reuse; 2189304d26faSStefano Zampini PetscScalar m_one = -1.0; 2190304d26faSStefano Zampini PetscReal value; 219104708bb6SStefano Zampini PetscInt n_D,n_R; 21929577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2193304d26faSStefano Zampini PetscErrorCode ierr; 2194e604994aSStefano Zampini /* prefixes stuff */ 2195312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2196e604994aSStefano Zampini size_t len; 2197304d26faSStefano Zampini 2198304d26faSStefano Zampini PetscFunctionBegin; 2199304d26faSStefano Zampini 2200e604994aSStefano Zampini /* compute prefixes */ 2201e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2202e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2203e604994aSStefano Zampini if (!pcbddc->current_level) { 2204e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2205e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2206e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2207e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2208e604994aSStefano Zampini } else { 2209e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2210312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2211e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2212e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2213312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2214312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 221534d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 221634d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2217e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2218e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2219e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2220e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2221e604994aSStefano Zampini } 2222e604994aSStefano Zampini 2223304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2224684f6988SStefano Zampini if (dirichlet) { 2225d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 22263301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 22273301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2228964fefecSStefano Zampini } 2229ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2230964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2231304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2232304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2233304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2234304d26faSStefano Zampini /* default */ 2235304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2236e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 22379577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2238304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 22399577ea80SStefano Zampini if (issbaij) { 22409577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 22419577ea80SStefano Zampini } else { 2242304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 22439577ea80SStefano Zampini } 2244304d26faSStefano Zampini /* Allow user's customization */ 2245304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2246304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2247304d26faSStefano Zampini } 2248d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 2249d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2250d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2251d62866d3SStefano Zampini 2252d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 2253d5574798SStefano Zampini } 2254304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2255304d26faSStefano Zampini if (!n_D) { 2256304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 2257304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2258304d26faSStefano Zampini } 2259304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 2260304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 2261304d26faSStefano Zampini /* set ksp_D into pcis data */ 2262304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 2263304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 2264304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 2265684f6988SStefano Zampini } 2266304d26faSStefano Zampini 2267304d26faSStefano Zampini /* NEUMANN PROBLEM */ 2268684f6988SStefano Zampini A_RR = 0; 2269684f6988SStefano Zampini if (neumann) { 2270d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 227104708bb6SStefano Zampini PetscInt ibs,mbs; 227204708bb6SStefano Zampini PetscBool issbaij; 227304708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2274f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 22758ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 2276f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 2277f4ddd8eeSStefano Zampini PetscInt nn_R; 227881d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 2279f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2280f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 2281f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 2282f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 2283f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2284f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2285f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 2286727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 2287f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2288f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2289f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 2290f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 2291f4ddd8eeSStefano Zampini } 2292f4ddd8eeSStefano Zampini } 2293f4ddd8eeSStefano Zampini /* last check */ 2294d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 2295f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2296f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2297f4ddd8eeSStefano Zampini } 2298f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 2299f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2300f4ddd8eeSStefano Zampini } 2301f4ddd8eeSStefano Zampini /* extract A_RR */ 2302af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 2303af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 230404708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 230504708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 230604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 230704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 230804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2309af732b37SStefano Zampini } else { 231004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 23116816873aSStefano Zampini } 231204708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 231304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 231404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 231504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 231604708bb6SStefano Zampini } else { 231704708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 231804708bb6SStefano Zampini } 231904708bb6SStefano Zampini } 232004708bb6SStefano Zampini if (!sub_schurs->reuse_mumps) { 2321f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 23223301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 23233301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 23246816873aSStefano Zampini } 23256816873aSStefano Zampini } else { 23266816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 23276816873aSStefano Zampini 23286816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 23296816873aSStefano Zampini ierr = PCGetOperators(reuse_mumps->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 23306816873aSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2331af732b37SStefano Zampini } 2332f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2333304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2334304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2335304d26faSStefano Zampini /* default */ 2336304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2337e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2338304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 23399577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 23409577ea80SStefano Zampini if (issbaij) { 23419577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 23429577ea80SStefano Zampini } else { 2343304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 23449577ea80SStefano Zampini } 2345304d26faSStefano Zampini /* Allow user's customization */ 2346304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2347304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2348304d26faSStefano Zampini } 2349d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2350304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2351304d26faSStefano Zampini if (!n_R) { 2352304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2353304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2354304d26faSStefano Zampini } 2355d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 2356d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2357d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2358d62866d3SStefano Zampini 2359d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 2360d62866d3SStefano Zampini } 2361304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2362304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2363684f6988SStefano Zampini } 23646816873aSStefano Zampini /* free Neumann problem's matrix */ 23656816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2366304d26faSStefano Zampini 2367304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 23680fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2369684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2370684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2371684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2372684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2373684f6988SStefano Zampini } 2374684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 23750fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 23760fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 23770fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 23780fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 23790fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2380304d26faSStefano Zampini /* need to be adapted? */ 2381b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2382b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2383b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2384304d26faSStefano Zampini /* print info */ 2385304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2386e604994aSStefano 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); 2387304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2388304d26faSStefano Zampini } 2389b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2390298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2391304d26faSStefano Zampini } 2392684f6988SStefano Zampini } 2393684f6988SStefano Zampini if (neumann) { /* Neumann */ 23946816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 23950fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 23960fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 23970fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 23980fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 23990fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2400304d26faSStefano Zampini /* need to be adapted? */ 2401b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2402b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2403304d26faSStefano Zampini /* print info */ 2404304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2405e604994aSStefano 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); 2406304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2407304d26faSStefano Zampini } 2408b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2409298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2410304d26faSStefano Zampini } 24110fccc4e9SStefano Zampini } 2412684f6988SStefano Zampini } 2413304d26faSStefano Zampini PetscFunctionReturn(0); 2414304d26faSStefano Zampini } 2415304d26faSStefano Zampini 2416304d26faSStefano Zampini #undef __FUNCT__ 2417ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 241880677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2419674ae819SStefano Zampini { 2420674ae819SStefano Zampini PetscErrorCode ierr; 2421674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2422be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2423674ae819SStefano Zampini 2424674ae819SStefano Zampini PetscFunctionBegin; 2425be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 242680677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 242720c7b377SStefano Zampini } 242880677318SStefano Zampini if (!pcbddc->switch_static) { 242980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 243080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 243180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 243220c7b377SStefano Zampini } 2433be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 243480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 243580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 243620c7b377SStefano Zampini } else { 2437be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2438be83ff47SStefano Zampini 243953892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 244053892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 244120c7b377SStefano Zampini } 2442be83ff47SStefano Zampini } else { 244380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244780677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 244880677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 244980677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 245080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 245180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2452674ae819SStefano Zampini } 2453674ae819SStefano Zampini } 2454be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 245580677318SStefano Zampini if (applytranspose) { 245680677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 245780677318SStefano Zampini } else { 245880677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 245980677318SStefano Zampini } 246053892102SStefano Zampini #if defined(PETSC_HAVE_MUMPS) 2461be83ff47SStefano Zampini } else { 2462be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2463be83ff47SStefano Zampini 2464be83ff47SStefano Zampini if (applytranspose) { 246553892102SStefano Zampini ierr = MatMumpsSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2466be83ff47SStefano Zampini } else { 246753892102SStefano Zampini ierr = MatMumpsSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2468be83ff47SStefano Zampini } 246953892102SStefano Zampini #endif 2470be83ff47SStefano Zampini } 247180677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 247280677318SStefano Zampini if (!pcbddc->switch_static) { 2473be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 247480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 247580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2476be83ff47SStefano Zampini } else { 2477be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2478be83ff47SStefano Zampini 247953892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 248053892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2481be83ff47SStefano Zampini } 248280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 248380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 248480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 248580677318SStefano Zampini } 248680677318SStefano Zampini } else { 248780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 249280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 249380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 249480677318SStefano Zampini } 249580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2499674ae819SStefano Zampini } 2500674ae819SStefano Zampini PetscFunctionReturn(0); 2501674ae819SStefano Zampini } 2502674ae819SStefano Zampini 2503dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2504674ae819SStefano Zampini #undef __FUNCT__ 2505674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2506dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2507674ae819SStefano Zampini { 2508674ae819SStefano Zampini PetscErrorCode ierr; 2509674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2510674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2511674ae819SStefano Zampini const PetscScalar zero = 0.0; 2512674ae819SStefano Zampini 2513674ae819SStefano Zampini PetscFunctionBegin; 2514dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2515dc359a40SStefano Zampini if (applytranspose) { 2516674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 25178eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2518dc359a40SStefano Zampini } else { 2519674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2520674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 252115aaf578SStefano Zampini } 2522efc2fbd9SStefano Zampini 2523efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 25244f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2525efc2fbd9SStefano Zampini PetscScalar *array; 25264f1b2e48SStefano Zampini PetscInt j; 2527efc2fbd9SStefano Zampini 2528efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 25294f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 2530efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2531efc2fbd9SStefano Zampini } 2532efc2fbd9SStefano Zampini 253312edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 253412edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 253512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253712edc857SStefano Zampini 25389f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 253912edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 254012edc857SStefano Zampini if (pcbddc->coarse_ksp) { 254151694757SStefano Zampini Mat coarse_mat; 2542964fefecSStefano Zampini Vec rhs,sol; 254351694757SStefano Zampini MatNullSpace nullsp; 2544964fefecSStefano Zampini 2545964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2546964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 254751694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 254851694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 254951694757SStefano Zampini if (nullsp) { 255051694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 255151694757SStefano Zampini } 255212edc857SStefano Zampini if (applytranspose) { 2553964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 255412edc857SStefano Zampini } else { 2555964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 255612edc857SStefano Zampini } 255751694757SStefano Zampini if (nullsp) { 255851694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 255951694757SStefano Zampini } 256012edc857SStefano Zampini } 2561674ae819SStefano Zampini 2562674ae819SStefano Zampini /* Local solution on R nodes */ 256380677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 256480677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 25659f00e9b4SStefano Zampini } 2566674ae819SStefano Zampini 25679f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 25689f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 256912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2570674ae819SStefano Zampini 2571674ae819SStefano Zampini /* Sum contributions from two levels */ 2572dc359a40SStefano Zampini if (applytranspose) { 2573dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2574dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2575dc359a40SStefano Zampini } else { 2576674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 25778eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2578dc359a40SStefano Zampini } 2579efc2fbd9SStefano Zampini /* store p0 */ 25804f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2581efc2fbd9SStefano Zampini PetscScalar *array; 25824f1b2e48SStefano Zampini PetscInt j; 2583efc2fbd9SStefano Zampini 2584efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 25854f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 2586efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2587efc2fbd9SStefano Zampini } 2588674ae819SStefano Zampini PetscFunctionReturn(0); 2589674ae819SStefano Zampini } 2590674ae819SStefano Zampini 2591674ae819SStefano Zampini #undef __FUNCT__ 2592674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 259312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2594674ae819SStefano Zampini { 2595674ae819SStefano Zampini PetscErrorCode ierr; 2596674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 259758da7f69SStefano Zampini PetscScalar *array; 259812edc857SStefano Zampini Vec from,to; 2599674ae819SStefano Zampini 2600674ae819SStefano Zampini PetscFunctionBegin; 260112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 260212edc857SStefano Zampini from = pcbddc->coarse_vec; 260312edc857SStefano Zampini to = pcbddc->vec1_P; 260412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 260512edc857SStefano Zampini Vec tvec; 260658da7f69SStefano Zampini 260758da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 260858da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 260912edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 261058da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 261158da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 261258da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 261312edc857SStefano Zampini } 261412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 261512edc857SStefano Zampini from = pcbddc->vec1_P; 261612edc857SStefano Zampini to = pcbddc->coarse_vec; 261712edc857SStefano Zampini } 261812edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 2619674ae819SStefano Zampini PetscFunctionReturn(0); 2620674ae819SStefano Zampini } 2621674ae819SStefano Zampini 2622674ae819SStefano Zampini #undef __FUNCT__ 2623674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 262412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 2625674ae819SStefano Zampini { 2626674ae819SStefano Zampini PetscErrorCode ierr; 2627674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 262858da7f69SStefano Zampini PetscScalar *array; 262912edc857SStefano Zampini Vec from,to; 2630674ae819SStefano Zampini 2631674ae819SStefano Zampini PetscFunctionBegin; 263212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 263312edc857SStefano Zampini from = pcbddc->coarse_vec; 263412edc857SStefano Zampini to = pcbddc->vec1_P; 263512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 263612edc857SStefano Zampini from = pcbddc->vec1_P; 263712edc857SStefano Zampini to = pcbddc->coarse_vec; 263812edc857SStefano Zampini } 263912edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 264012edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 264112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 264212edc857SStefano Zampini Vec tvec; 264358da7f69SStefano Zampini 264412edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 264558da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 264658da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 264758da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 264858da7f69SStefano Zampini } 264958da7f69SStefano Zampini } else { 265058da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 265158da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 265212edc857SStefano Zampini } 265312edc857SStefano Zampini } 2654674ae819SStefano Zampini PetscFunctionReturn(0); 2655674ae819SStefano Zampini } 2656674ae819SStefano Zampini 2657984c4197SStefano Zampini /* uncomment for testing purposes */ 2658984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 2659674ae819SStefano Zampini #undef __FUNCT__ 2660674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 2661674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 2662674ae819SStefano Zampini { 2663674ae819SStefano Zampini PetscErrorCode ierr; 2664674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2665674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2666674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2667984c4197SStefano Zampini /* one and zero */ 2668984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 2669984c4197SStefano Zampini /* space to store constraints and their local indices */ 26709162d606SStefano Zampini PetscScalar *constraints_data; 26719162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 26729162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 26739162d606SStefano Zampini PetscInt *constraints_n; 2674984c4197SStefano Zampini /* iterators */ 2675b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 2676984c4197SStefano Zampini /* BLAS integers */ 2677e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2678e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2679c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2680727cdba6SStefano Zampini /* reuse */ 26810e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 26820e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2683984c4197SStefano Zampini /* change of basis */ 2684b3d85658SStefano Zampini PetscBool qr_needed; 26859162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2686984c4197SStefano Zampini /* auxiliary stuff */ 268764efe560SStefano Zampini PetscInt *nnz,*is_indices; 26888a0068c3SStefano Zampini PetscInt ncc; 2689984c4197SStefano Zampini /* some quantities */ 269045a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2691a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2692984c4197SStefano Zampini 2693674ae819SStefano Zampini PetscFunctionBegin; 26948e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 26958e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 26968e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2697088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2698088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 26990e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 27000e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 27010e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 27020e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 27030e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2704088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2705cf5a6209SStefano Zampini 2706cf5a6209SStefano Zampini /* print some info */ 2707cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2708cf5a6209SStefano Zampini IS vertices; 2709cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2710cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2711cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2712cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2713cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2714cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2715cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2716fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2717fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2718cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2719cf5a6209SStefano Zampini } 2720cf5a6209SStefano Zampini 2721cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 27229162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2723cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2724cf5a6209SStefano Zampini const Vec *nearnullvecs; 2725cf5a6209SStefano Zampini Vec *localnearnullsp; 2726cf5a6209SStefano Zampini PetscScalar *array; 2727cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2728cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2729674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2730b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2731674ae819SStefano Zampini PetscScalar *work; 2732674ae819SStefano Zampini PetscReal *singular_vals; 2733674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2734674ae819SStefano Zampini PetscReal *rwork; 2735674ae819SStefano Zampini #endif 2736674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2737674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2738674ae819SStefano Zampini #else 2739964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2740964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2741674ae819SStefano Zampini #endif 2742674ae819SStefano Zampini 2743674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2744d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2745d06fc5fdSStefano Zampini /* free unneeded index sets */ 2746d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2747d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2748674ae819SStefano Zampini } 2749d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2750d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2751d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2752d06fc5fdSStefano Zampini } 2753d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2754d06fc5fdSStefano Zampini n_ISForEdges = 0; 2755d06fc5fdSStefano Zampini } 2756d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2757d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2758d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2759d06fc5fdSStefano Zampini } 2760d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2761d06fc5fdSStefano Zampini n_ISForFaces = 0; 2762d06fc5fdSStefano Zampini } 276370022509SStefano Zampini 276470022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 276570022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 276670022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 276770022509SStefano Zampini if (pcbddc->NullSpace) { 276870022509SStefano Zampini PetscBool tbool[2],gbool[2]; 276970022509SStefano Zampini 277070022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2771b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2772d06fc5fdSStefano Zampini if (!ISForEdges) { 2773d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2774d06fc5fdSStefano Zampini } 2775b8ffe317SStefano Zampini } 2776d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2777d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2778d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2779d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2780d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 278198a51de6SStefano Zampini } 278270022509SStefano Zampini #endif 278308122e43SStefano Zampini 2784674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2785674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2786674ae819SStefano Zampini if (nearnullsp) { 2787674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2788f4ddd8eeSStefano Zampini /* remove any stored info */ 2789f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2790f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2791f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2792f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2793f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2794473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2795f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2796f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2797f4ddd8eeSStefano Zampini } 2798984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2799984c4197SStefano Zampini nnsp_size = 0; 2800674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2801674ae819SStefano Zampini } 2802984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2803984c4197SStefano Zampini max_constraints = nnsp_size; 2804984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2805984c4197SStefano Zampini 2806674ae819SStefano Zampini /* 2807674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 28089162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 28099162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 28109162d606SStefano Zampini There can be multiple constraints per connected component 2811674ae819SStefano Zampini */ 2812674ae819SStefano Zampini n_vertices = 0; 2813674ae819SStefano Zampini if (ISForVertices) { 2814674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2815674ae819SStefano Zampini } 28169162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 28179162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 28189162d606SStefano Zampini 28199162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 28209162d606SStefano Zampini total_counts *= max_constraints; 2821674ae819SStefano Zampini total_counts += n_vertices; 28224641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 28239162d606SStefano Zampini 2824674ae819SStefano Zampini total_counts = 0; 2825674ae819SStefano Zampini max_size_of_constraint = 0; 2826674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 28279162d606SStefano Zampini IS used_is; 2828674ae819SStefano Zampini if (i<n_ISForEdges) { 28299162d606SStefano Zampini used_is = ISForEdges[i]; 2830674ae819SStefano Zampini } else { 28319162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2832674ae819SStefano Zampini } 28339162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2834674ae819SStefano Zampini total_counts += j; 2835674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2836674ae819SStefano Zampini } 28379162d606SStefano 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); 28389162d606SStefano Zampini 2839984c4197SStefano Zampini /* get local part of global near null space vectors */ 2840785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2841984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2842984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2843e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2844e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2845984c4197SStefano Zampini } 2846674ae819SStefano Zampini 2847242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2848242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2849a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2850242a89d7SStefano Zampini 2851984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2852a773dcb8SStefano Zampini if (!skip_lapack) { 2853674ae819SStefano Zampini PetscScalar temp_work; 2854911cabfeSStefano Zampini 2855674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2856984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2857785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2858785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2859785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2860674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2861785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2862674ae819SStefano Zampini #endif 2863674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2864c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2865c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2866674ae819SStefano Zampini lwork = -1; 2867674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2868674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2869c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2870674ae819SStefano Zampini #else 2871c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2872674ae819SStefano Zampini #endif 2873674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2874984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2875674ae819SStefano Zampini #else /* on missing GESVD */ 2876674ae819SStefano Zampini /* SVD */ 2877674ae819SStefano Zampini PetscInt max_n,min_n; 2878674ae819SStefano Zampini max_n = max_size_of_constraint; 2879984c4197SStefano Zampini min_n = max_constraints; 2880984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2881674ae819SStefano Zampini min_n = max_size_of_constraint; 2882984c4197SStefano Zampini max_n = max_constraints; 2883674ae819SStefano Zampini } 2884785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2885674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2886785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2887674ae819SStefano Zampini #endif 2888674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2889674ae819SStefano Zampini lwork = -1; 2890e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2891e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2892b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2893674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2894674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 28959162d606SStefano 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)); 2896674ae819SStefano Zampini #else 28979162d606SStefano 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)); 2898674ae819SStefano Zampini #endif 2899674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2900984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2901984c4197SStefano Zampini #endif /* on missing GESVD */ 2902674ae819SStefano Zampini /* Allocate optimal workspace */ 2903674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2904854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2905674ae819SStefano Zampini } 2906674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2907674ae819SStefano Zampini total_counts = 0; 29089162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 29099162d606SStefano Zampini constraints_data_ptr[0] = 0; 2910674ae819SStefano Zampini /* vertices */ 29119162d606SStefano Zampini if (n_vertices) { 2912674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 29139162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2914674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 29159162d606SStefano Zampini constraints_n[total_counts] = 1; 29169162d606SStefano Zampini constraints_data[total_counts] = 1.0; 29179162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 29189162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2919674ae819SStefano Zampini total_counts++; 2920674ae819SStefano Zampini } 2921674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2922674ae819SStefano Zampini n_vertices = total_counts; 2923674ae819SStefano Zampini } 2924984c4197SStefano Zampini 2925674ae819SStefano Zampini /* edges and faces */ 29269162d606SStefano Zampini total_counts_cc = total_counts; 2927911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 29289162d606SStefano Zampini IS used_is; 29299162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 29309162d606SStefano Zampini 2931911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 29329162d606SStefano Zampini used_is = ISForEdges[ncc]; 2933984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2934674ae819SStefano Zampini } else { 29359162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2936984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2937674ae819SStefano Zampini } 2938674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 29399162d606SStefano Zampini 29409162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 29419162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2942984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2943984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2944674ae819SStefano Zampini if (nnsp_has_cnst) { 29455b08dc53SStefano Zampini PetscScalar quad_value; 29469162d606SStefano Zampini 29479162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 29489162d606SStefano Zampini idxs_copied = PETSC_TRUE; 29499162d606SStefano Zampini 2950a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2951674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2952a773dcb8SStefano Zampini } else { 2953a773dcb8SStefano Zampini quad_value = 1.0; 2954a773dcb8SStefano Zampini } 2955674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 29569162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 2957674ae819SStefano Zampini } 29589162d606SStefano Zampini temp_constraints++; 2959674ae819SStefano Zampini total_counts++; 2960674ae819SStefano Zampini } 2961674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2962984c4197SStefano Zampini PetscReal real_value; 29639162d606SStefano Zampini PetscScalar *ptr_to_data; 29649162d606SStefano Zampini 2965984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 29669162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 2967674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 29689162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 2969674ae819SStefano Zampini } 2970984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2971984c4197SStefano Zampini /* check if array is null on the connected component */ 2972e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 29739162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 29745b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2975674ae819SStefano Zampini temp_constraints++; 2976674ae819SStefano Zampini total_counts++; 29779162d606SStefano Zampini if (!idxs_copied) { 29789162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 29799162d606SStefano Zampini idxs_copied = PETSC_TRUE; 2980674ae819SStefano Zampini } 2981674ae819SStefano Zampini } 29829162d606SStefano Zampini } 29839162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 298445a1bb75SStefano Zampini valid_constraints = temp_constraints; 2985eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2986a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 29879162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 29889162d606SStefano Zampini 29899162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2990a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 29919162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 2992a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 29939162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 2994a773dcb8SStefano Zampini } else { /* perform SVD */ 2995984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 29969162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2997674ae819SStefano Zampini 2998674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2999984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3000984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3001984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3002984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3003984c4197SStefano Zampini from that computed using LAPACKgesvd 3004984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3005984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3006984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3007674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3008e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3009984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3010674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3011674ae819SStefano Zampini for (k=0;k<j+1;k++) { 30129162d606SStefano 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)); 3013674ae819SStefano Zampini } 3014674ae819SStefano Zampini } 3015e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3016e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3017e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3018674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3019c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3020674ae819SStefano Zampini #else 3021c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3022674ae819SStefano Zampini #endif 3023674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3024984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3025984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3026674ae819SStefano Zampini j = 0; 3027984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3028674ae819SStefano Zampini total_counts = total_counts-j; 302945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3030e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3031c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3032c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3033c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3034c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3035c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3036c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3037674ae819SStefano Zampini if (j<temp_constraints) { 3038984c4197SStefano Zampini PetscInt ii; 3039984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3040674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30419162d606SStefano 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)); 3042674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3043984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3044674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 30459162d606SStefano 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]; 3046674ae819SStefano Zampini } 3047674ae819SStefano Zampini } 3048674ae819SStefano Zampini } 3049674ae819SStefano Zampini #else /* on missing GESVD */ 3050e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3051e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3052b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3053674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3054674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 30559162d606SStefano 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)); 3056674ae819SStefano Zampini #else 30579162d606SStefano 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)); 3058674ae819SStefano Zampini #endif 3059984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3060674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3061984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3062e310c8b4SStefano Zampini k = temp_constraints; 3063e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3064674ae819SStefano Zampini j = 0; 3065e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 306645a1bb75SStefano Zampini valid_constraints = k-j; 3067911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3068984c4197SStefano Zampini #endif /* on missing GESVD */ 3069674ae819SStefano Zampini } 3070a773dcb8SStefano Zampini } 30719162d606SStefano Zampini /* update pointers information */ 30729162d606SStefano Zampini if (valid_constraints) { 30739162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 30749162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 30759162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 30769162d606SStefano Zampini /* set change_of_basis flag */ 307745a1bb75SStefano Zampini if (boolforchange) { 3078b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 30799162d606SStefano Zampini } 3080b3d85658SStefano Zampini total_counts_cc++; 308145a1bb75SStefano Zampini } 308245a1bb75SStefano Zampini } 3083984c4197SStefano Zampini /* free workspace */ 30848f1c130eSStefano Zampini if (!skip_lapack) { 3085984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3086984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3087984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3088984c4197SStefano Zampini #endif 3089984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3090984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3091984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3092984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3093984c4197SStefano Zampini #endif 3094984c4197SStefano Zampini } 3095984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3096984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3097984c4197SStefano Zampini } 3098984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3099cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3100cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3101cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3102cf5a6209SStefano Zampini } 3103cf5a6209SStefano Zampini if (n_ISForFaces) { 3104cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3105cf5a6209SStefano Zampini } 3106cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3107cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3108cf5a6209SStefano Zampini } 3109cf5a6209SStefano Zampini if (n_ISForEdges) { 3110cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3111cf5a6209SStefano Zampini } 3112cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 311308122e43SStefano Zampini } else { 311408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3115984c4197SStefano Zampini 311608122e43SStefano Zampini total_counts = 0; 311708122e43SStefano Zampini n_vertices = 0; 3118d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3119d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 312008122e43SStefano Zampini } 312108122e43SStefano Zampini max_constraints = 0; 31229162d606SStefano Zampini total_counts_cc = 0; 312308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 312408122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 31259162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 312608122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 312708122e43SStefano Zampini } 31289162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 31299162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 31309162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 31319162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 313274d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 31339162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 31349162d606SStefano Zampini total_counts_cc = 0; 31359162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 31369162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 31379162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 313808122e43SStefano Zampini } 313908122e43SStefano Zampini } 31409162d606SStefano Zampini #if 0 31419162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 31429162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 31439162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 31449162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 31459162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 31469162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 31479162d606SStefano Zampini } 31489162d606SStefano Zampini printf("\n"); 31499162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 31509162d606SStefano Zampini } 31511b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 31528bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 31531b968477SStefano Zampini } 31541b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 31558bec7fa6SStefano 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]); 31561b968477SStefano Zampini } 315708122e43SStefano Zampini #endif 315808122e43SStefano Zampini 31598bec7fa6SStefano Zampini max_size_of_constraint = 0; 31609162d606SStefano 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]); 31619162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 316208122e43SStefano Zampini /* Change of basis */ 3163b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 316408122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 316508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 316608122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3167b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 316808122e43SStefano Zampini } 316908122e43SStefano Zampini } 317008122e43SStefano Zampini } 317108122e43SStefano Zampini } 3172984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 31734f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 317408122e43SStefano Zampini 31759162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 31769162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 31779162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 31789162d606SStefano 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); 317908122e43SStefano Zampini } 3180674ae819SStefano Zampini 3181674ae819SStefano Zampini /* Create constraint matrix */ 3182674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 318316f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3184984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3185984c4197SStefano Zampini 3186984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3187a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3188a717540cSStefano Zampini qr_needed = PETSC_FALSE; 318974d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3190984c4197SStefano Zampini total_primal_vertices=0; 3191b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 31929162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 31939162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3194984c4197SStefano Zampini if (size_of_constraint == 1) { 31959162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 3196b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 319764efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 31989162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 31999162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 3200a717540cSStefano Zampini } 3201b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 320274d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 3203a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 3204a717540cSStefano Zampini qr_needed = PETSC_TRUE; 3205a717540cSStefano Zampini } 3206fa434743SStefano Zampini } else { 3207b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 3208fa434743SStefano Zampini } 3209a717540cSStefano Zampini } 3210b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 3211b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 3212674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 321370022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3214b3d85658SStefano Zampini 32154f1b2e48SStefano 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); 32160e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 32170e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 3218984c4197SStefano Zampini 3219984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 322074d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 3221785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 3222984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 322374d5cdf7SStefano Zampini 3224984c4197SStefano Zampini j = total_primal_vertices; 322574d5cdf7SStefano Zampini total_counts = total_primal_vertices; 3226b3d85658SStefano Zampini cum = total_primal_vertices; 32279162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32284641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 3229b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 3230b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 3231b3d85658SStefano Zampini cum++; 32329162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 323374d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 323474d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 323574d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 323674d5cdf7SStefano Zampini } 32379162d606SStefano Zampini j += constraints_n[i]; 3238674ae819SStefano Zampini } 3239674ae819SStefano Zampini } 3240674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 3241674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3242088faed8SStefano Zampini 3243674ae819SStefano Zampini /* set values in constraint matrix */ 3244984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 32450e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3246674ae819SStefano Zampini } 3247984c4197SStefano Zampini total_counts = total_primal_vertices; 32489162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32494641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 32509162d606SStefano Zampini PetscInt *cols; 32519162d606SStefano Zampini 32529162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 32539162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 32549162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 32559162d606SStefano Zampini PetscInt row = total_counts+k; 32569162d606SStefano Zampini PetscScalar *vals; 32579162d606SStefano Zampini 32589162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 32599162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 32609162d606SStefano Zampini } 32619162d606SStefano Zampini total_counts += constraints_n[i]; 3262674ae819SStefano Zampini } 3263674ae819SStefano Zampini } 3264674ae819SStefano Zampini /* assembling */ 3265674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3266674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3267088faed8SStefano Zampini 3268984c4197SStefano Zampini /* 326945a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3270984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 3271984c4197SStefano Zampini */ 3272674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 3273674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 3274026de310SStefano Zampini /* dual and primal dofs on a single cc */ 3275984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 3276984c4197SStefano Zampini /* working stuff for GEQRF */ 327781d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 3278984c4197SStefano Zampini PetscBLASInt lqr_work; 3279984c4197SStefano Zampini /* working stuff for UNGQR */ 3280984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 3281984c4197SStefano Zampini PetscBLASInt lgqr_work; 3282984c4197SStefano Zampini /* working stuff for TRTRS */ 3283984c4197SStefano Zampini PetscScalar *trs_rhs; 32843f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 3285984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 3286984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 3287984c4197SStefano Zampini PetscScalar *start_vals; 3288984c4197SStefano Zampini /* working stuff for values insertion */ 32894641a718SStefano Zampini PetscBT is_primal; 329064efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 3291906d46d4SStefano Zampini /* matrix sizes */ 3292906d46d4SStefano Zampini PetscInt global_size,local_size; 3293906d46d4SStefano Zampini /* temporary change of basis */ 3294906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 3295cf5a6209SStefano Zampini /* extra space for debugging */ 3296cf5a6209SStefano Zampini PetscScalar *dbg_work; 3297984c4197SStefano Zampini 3298906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 3299906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 330016f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 3301bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3302906d46d4SStefano Zampini /* nonzeros for local mat */ 3303bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 3304bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 33059162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 3306a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 33079162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3308a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 33099162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3310a717540cSStefano Zampini } else { 33119162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 33129162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3313a717540cSStefano Zampini } 3314a717540cSStefano Zampini } 3315a717540cSStefano Zampini } 3316906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3317bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3318a717540cSStefano Zampini /* Set initial identity in the matrix */ 3319bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3320906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3321a717540cSStefano Zampini } 3322a717540cSStefano Zampini 3323a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3324a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3325a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3326a717540cSStefano Zampini } 3327a717540cSStefano Zampini 3328a717540cSStefano Zampini 3329a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3330a717540cSStefano Zampini /* 3331a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3332a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3333a717540cSStefano Zampini 3334a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3335a717540cSStefano Zampini 3336a6b551f4SStefano 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) 3337a6b551f4SStefano Zampini 3338a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3339a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3340a717540cSStefano Zampini | ... | 3341a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3342a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3343a717540cSStefano Zampini 3344a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3345a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3346a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3347a6b551f4SStefano Zampini 3348a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3349a717540cSStefano Zampini */ 3350a717540cSStefano Zampini if (qr_needed) { 3351984c4197SStefano Zampini /* space to store Q */ 3352854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3353984c4197SStefano Zampini /* first we issue queries for optimal work */ 33543f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 33553f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 33563f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3357984c4197SStefano Zampini lqr_work = -1; 33583f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3359984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3360984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3361785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3362984c4197SStefano Zampini lgqr_work = -1; 33633f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 33643f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 33653f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 33663f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 33673f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 33683f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3369984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3370984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3371785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3372984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3373785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3374984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3375785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3376a717540cSStefano Zampini /* allocating workspace for check */ 3377a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3378cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3379a717540cSStefano Zampini } 3380a717540cSStefano Zampini } 3381984c4197SStefano Zampini /* array to store whether a node is primal or not */ 33824641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3383473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 33840e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 338539e2fb2aSStefano Zampini if (i != total_primal_vertices) { 338639e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 33874641a718SStefano Zampini } 338839e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 338939e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 339039e2fb2aSStefano Zampini } 339139e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3392984c4197SStefano Zampini 3393a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 33949162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 33959162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 33964641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3397984c4197SStefano Zampini /* get constraint info */ 33989162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3399984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3400984c4197SStefano Zampini 3401984c4197SStefano Zampini if (pcbddc->dbg_flag) { 34029162d606SStefano 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); 3403674ae819SStefano Zampini } 3404984c4197SStefano Zampini 3405fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3406a717540cSStefano Zampini 3407a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3408a717540cSStefano Zampini if (pcbddc->dbg_flag) { 34099162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3410a717540cSStefano Zampini } 3411984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 34129162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3413984c4197SStefano Zampini 3414984c4197SStefano Zampini /* compute QR decomposition of constraints */ 34153f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34163f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34173f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3418674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34193f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3420984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3421674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3422984c4197SStefano Zampini 3423984c4197SStefano Zampini /* explictly compute R^-T */ 3424984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3425984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 34263f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 34283f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34293f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3430984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34313f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3432984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3433984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3434984c4197SStefano Zampini 3435a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 34363f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34373f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34383f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34393f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3440984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34413f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3442984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3443984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3444984c4197SStefano Zampini 3445984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3446984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3447984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 34483f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34493f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34503f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34513f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34523f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 34533f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3454984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34559162d606SStefano 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)); 3456984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 34579162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3458984c4197SStefano Zampini 3459984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 34609162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3461984c4197SStefano Zampini /* insert cols for primal dofs */ 3462984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3463984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 34649162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3465906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3466984c4197SStefano Zampini } 3467984c4197SStefano Zampini /* insert cols for dual dofs */ 3468984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 34699162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3470984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 34719162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3472906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3473984c4197SStefano Zampini j++; 3474674ae819SStefano Zampini } 3475674ae819SStefano Zampini } 3476984c4197SStefano Zampini 3477984c4197SStefano Zampini /* check change of basis */ 3478984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3479984c4197SStefano Zampini PetscInt ii,jj; 3480984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3481c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3482c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3483c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3484c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3485c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3486c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3487984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3488cf5a6209SStefano 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)); 3489984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3490984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3491984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3492cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3493cf5a6209SStefano 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; 3494674ae819SStefano Zampini } 3495674ae819SStefano Zampini } 3496984c4197SStefano Zampini if (!valid_qr) { 349722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3498984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3499984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3500cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3501cf5a6209SStefano 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])); 3502674ae819SStefano Zampini } 3503cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3504cf5a6209SStefano 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])); 3505984c4197SStefano Zampini } 3506984c4197SStefano Zampini } 3507984c4197SStefano Zampini } 3508674ae819SStefano Zampini } else { 350922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3510674ae819SStefano Zampini } 3511674ae819SStefano Zampini } 3512a717540cSStefano Zampini } else { /* simple transformation block */ 3513a717540cSStefano Zampini PetscInt row,col; 3514a6b551f4SStefano Zampini PetscScalar val,norm; 3515a6b551f4SStefano Zampini 3516a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 35179162d606SStefano 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)); 3518a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 35199162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 35209162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3521bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 35229162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3523906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 35249162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3525a717540cSStefano Zampini } else { 3526a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 35279162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3528a717540cSStefano Zampini if (row != col) { 35299162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3530a717540cSStefano Zampini } else { 35319162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3532a717540cSStefano Zampini } 3533906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3534a717540cSStefano Zampini } 3535a717540cSStefano Zampini } 3536a717540cSStefano Zampini } 353798a51de6SStefano Zampini if (pcbddc->dbg_flag) { 353822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3539a717540cSStefano Zampini } 3540674ae819SStefano Zampini } 3541984c4197SStefano Zampini } else { 3542984c4197SStefano Zampini if (pcbddc->dbg_flag) { 35439162d606SStefano 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); 3544674ae819SStefano Zampini } 3545674ae819SStefano Zampini } 3546674ae819SStefano Zampini } 3547a717540cSStefano Zampini 3548a717540cSStefano Zampini /* free workspace */ 3549a717540cSStefano Zampini if (qr_needed) { 3550984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3551cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3552984c4197SStefano Zampini } 3553984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3554984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3555984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3556984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3557984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3558674ae819SStefano Zampini } 3559a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3560906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3561906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3562906d46d4SStefano Zampini 3563906d46d4SStefano Zampini /* assembling of global change of variable */ 3564bbb9e6c6SStefano Zampini { 3565bbb9e6c6SStefano Zampini Mat tmat; 356616f15bc4SStefano Zampini PetscInt bs; 356716f15bc4SStefano Zampini 3568906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3569906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3570bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3571bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3572bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3573bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 357416f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 357516f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3576906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3577bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3578bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3579bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3580bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3581bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3582e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3583e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3584bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3585bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3586906d46d4SStefano Zampini } 3587906d46d4SStefano Zampini /* check */ 3588906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3589906d46d4SStefano Zampini PetscReal error; 3590906d46d4SStefano Zampini Vec x,x_change; 3591906d46d4SStefano Zampini 3592906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3593906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3594906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3595906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3596e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3597e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3598bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 3599e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3600e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3601906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 3602906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3603906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3604906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3605bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 3606906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3607906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3608906d46d4SStefano Zampini } 3609b96c3477SStefano Zampini 3610b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 3611b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3612b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 3613b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 3614ac632422SStefano Zampini Mat S_new,tmat; 3615b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 3616b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 3617b087196eSStefano Zampini const PetscScalar *array; 3618b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 3619b087196eSStefano Zampini PetscInt i,n_V; 3620bbb9e6c6SStefano Zampini 3621bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 36226816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 3623b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 3624b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 3625b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 3626b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 3627bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 3628b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 3629ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3630b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 3631ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3632b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3633b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 3634b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3635b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3636b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 3637b087196eSStefano Zampini for (i=0;i<n_V;i++) { 3638b087196eSStefano Zampini PetscScalar val; 3639b087196eSStefano Zampini PetscInt idx; 3640b087196eSStefano Zampini 3641b087196eSStefano Zampini idx = idxs_V[i]; 3642b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 3643b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 3644b087196eSStefano Zampini } 3645b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3646b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3647ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 3648ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3649ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 3650ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3651b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 3652ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3653b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3654ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 3655ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3656ac632422SStefano Zampini } 3657b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 3658b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3659b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3660b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3661b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 3662b96c3477SStefano Zampini } 3663b96c3477SStefano Zampini } 3664906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 3665906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 3666b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3667b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 3668b9b85e73SStefano Zampini } 3669906d46d4SStefano Zampini 3670906d46d4SStefano Zampini /* set up change of basis context */ 3671906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 3672906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 3673906d46d4SStefano Zampini 3674906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 3675906d46d4SStefano Zampini PetscInt global_size,local_size; 3676906d46d4SStefano Zampini 3677906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3678906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3679906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 3680906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3681906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 3682906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 3683906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3684906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3685906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3686906d46d4SStefano Zampini } else { 3687906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3688906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3689906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3690906d46d4SStefano Zampini } 3691906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3692906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3693906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3694906d46d4SStefano Zampini } else { 3695906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3696906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3697906d46d4SStefano Zampini } 3698906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3699906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3700906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3701906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3702b9b85e73SStefano Zampini } 3703a717540cSStefano Zampini 37044f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 37054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 37064f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 37074f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 3708019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 3709019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 3710019a44ceSStefano Zampini pcbddc->local_primal_size++; 3711019a44ceSStefano Zampini } 3712019a44ceSStefano Zampini 3713019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 3714727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3715727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 3716*9f47a83aSStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3717c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 37180e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 3719*9f47a83aSStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3720727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3721727cdba6SStefano Zampini } 37220e6343abSStefano Zampini } 37230e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3724727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3725727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3726727cdba6SStefano Zampini 3727a717540cSStefano Zampini /* flush dbg viewer */ 3728b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3729b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3730b8ffe317SStefano Zampini } 3731a717540cSStefano Zampini 3732e310c8b4SStefano Zampini /* free workspace */ 3733a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 37344641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 373508122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 37369162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 37379162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 373808122e43SStefano Zampini } else { 37399162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 37409162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 37419162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 374208122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 374308122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 37449162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 37459162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 374608122e43SStefano Zampini } 3747674ae819SStefano Zampini PetscFunctionReturn(0); 3748674ae819SStefano Zampini } 3749674ae819SStefano Zampini 3750674ae819SStefano Zampini #undef __FUNCT__ 3751674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3752674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3753674ae819SStefano Zampini { 3754674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3755674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3756674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 37577fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3758674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3759674ae819SStefano Zampini 3760674ae819SStefano Zampini PetscFunctionBegin; 37618e61c736SStefano Zampini /* Reset previously computed graph */ 37628e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3763674ae819SStefano Zampini /* Init local Graph struct */ 37647fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 37653bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3766674ae819SStefano Zampini 3767575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 37685099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 37695099eff2SStefano 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); 3770575ad6abSStefano Zampini } 37719577ea80SStefano Zampini 3772674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 37734d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 37744d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 37754d379d7bSStefano Zampini PetscInt nvtxs; 3776e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3777674ae819SStefano Zampini 37784d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 37792fffb893SStefano Zampini 37802fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 37812fffb893SStefano Zampini if (flg_row) { 37824d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3783b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 37842fffb893SStefano Zampini } 37852fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 37869b28b941SStefano 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 */ 37874d379d7bSStefano Zampini IS is_dummy; 37884d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 37894d379d7bSStefano Zampini PetscInt j,sum; 37904d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 37914d379d7bSStefano Zampini const PetscInt *idxs; 37924d379d7bSStefano Zampini PCBDDCGraph graph; 37934d379d7bSStefano Zampini PetscBT is_on_boundary; 37944d379d7bSStefano Zampini 37954d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 37964d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 37974d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 37984d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 37997fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 38004d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3801e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3802e496cd5dSStefano Zampini if (flg_row) { 38034d379d7bSStefano Zampini graph->xadj = xadj; 38044d379d7bSStefano Zampini graph->adjncy = adjncy; 3805e496cd5dSStefano Zampini } 38064d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 38074d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3808e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 38094d379d7bSStefano Zampini 38104d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 38119b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 38124d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38134d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 38144d379d7bSStefano Zampini } 38154d379d7bSStefano Zampini } 38164d379d7bSStefano Zampini 3817e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 38184d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38194d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 38204d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 38214d379d7bSStefano Zampini } 38224d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38234d379d7bSStefano Zampini 3824e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 38254d379d7bSStefano Zampini sum = 0; 38264d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38274d379d7bSStefano Zampini PetscInt sizecc = 0; 38284d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38294d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38304d379d7bSStefano Zampini sizecc++; 38314d379d7bSStefano Zampini } 38324d379d7bSStefano Zampini } 38334d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38344d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38354d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 38364d379d7bSStefano Zampini } 38374d379d7bSStefano Zampini } 38384d379d7bSStefano Zampini sum += sizecc*sizecc; 38394d379d7bSStefano Zampini } 38404d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 38414d379d7bSStefano Zampini sum = 0; 3842e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 38434d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 38444d379d7bSStefano Zampini cxadj[i] = sum; 38454d379d7bSStefano Zampini sum += temp; 38464d379d7bSStefano Zampini } 3847e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 38484d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38494d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38504d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38514d379d7bSStefano Zampini PetscInt k,sizecc = 0; 38524d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 38534d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 38544d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 38554d379d7bSStefano Zampini sizecc++; 38564d379d7bSStefano Zampini } 38574d379d7bSStefano Zampini } 38584d379d7bSStefano Zampini } 38594d379d7bSStefano Zampini } 38604d379d7bSStefano Zampini } 38619b28b941SStefano Zampini if (sum) { 3862e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 38634d379d7bSStefano Zampini } else { 38644d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 38654d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 38664d379d7bSStefano Zampini } 38674d379d7bSStefano Zampini graph->xadj = 0; 38684d379d7bSStefano Zampini graph->adjncy = 0; 38694d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 38704d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 38714d379d7bSStefano Zampini } 3872674ae819SStefano Zampini } 38739b28b941SStefano Zampini if (pcbddc->dbg_flag) { 38749b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3875674ae819SStefano Zampini } 3876674ae819SStefano Zampini 387763602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3878674ae819SStefano Zampini vertex_size = 1; 387963602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 388063602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 388195ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 388263602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3883e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 388463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3885674ae819SStefano Zampini } 388663602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 388763602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 388863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3889674ae819SStefano Zampini } 389063602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3891674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 389263602bcaSStefano Zampini } else { 389363602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 389463602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3895854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 389663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 389763602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 389863602bcaSStefano Zampini } 389963602bcaSStefano Zampini } 3900674ae819SStefano Zampini } 3901674ae819SStefano Zampini 3902674ae819SStefano Zampini /* Setup of Graph */ 3903785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3904e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3905785d1243SStefano Zampini } 3906785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3907e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3908785d1243SStefano Zampini } 3909302440fdSBarry Smith ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices);CHKERRQ(ierr); 3910674ae819SStefano Zampini 39114f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 39124f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 39134f1b2e48SStefano Zampini PetscInt *local_subs; 39144f1b2e48SStefano Zampini 39154f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 39164f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 39174f1b2e48SStefano Zampini const PetscInt *idxs; 39184f1b2e48SStefano Zampini PetscInt nl,j; 39194f1b2e48SStefano Zampini 39204f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 39214f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39224f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 39234f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 39244f1b2e48SStefano Zampini } 39254f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39264f1b2e48SStefano Zampini } 39274f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 39284f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 39294f1b2e48SStefano Zampini } 39304f1b2e48SStefano Zampini 3931674ae819SStefano Zampini /* Graph's connected components analysis */ 3932674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3933674ae819SStefano Zampini 3934674ae819SStefano Zampini /* print some info to stdout */ 3935674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3936302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3937674ae819SStefano Zampini } 3938fb180af4SStefano Zampini 3939fb180af4SStefano Zampini /* mark topography has done */ 3940fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3941674ae819SStefano Zampini PetscFunctionReturn(0); 3942674ae819SStefano Zampini } 3943674ae819SStefano Zampini 3944dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3945674ae819SStefano Zampini #undef __FUNCT__ 3946674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3947dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3948674ae819SStefano Zampini { 3949dc456d91SStefano Zampini PetscSF sf; 3950dc456d91SStefano Zampini PetscLayout map; 3951dc456d91SStefano Zampini const PetscInt *idxs; 3952dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 3953dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 3954dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 3955dc456d91SStefano Zampini PetscMPIInt commsize; 3956674ae819SStefano Zampini PetscBool first_found; 3957674ae819SStefano Zampini PetscErrorCode ierr; 3958674ae819SStefano Zampini 3959674ae819SStefano Zampini PetscFunctionBegin; 3960dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 3961dc456d91SStefano Zampini if (subset_mult) { 3962dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 3963dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 3964dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 3965674ae819SStefano Zampini } 3966dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 3967dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 3968dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 3969dc456d91SStefano Zampini for (i=0;i<n;i++) { 3970dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 3971dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 3972674ae819SStefano Zampini } 3973dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 3974dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3975dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 3976dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 3977dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 3978dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 3979dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 3980dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 3981dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 3982dc456d91SStefano Zampini 3983dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 3984dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 3985dc456d91SStefano Zampini if (subset_mult) { 3986dc456d91SStefano Zampini const PetscInt* idxs_mult; 3987dc456d91SStefano Zampini 3988dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3989dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 3990dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3991674ae819SStefano Zampini } else { 3992dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 3993674ae819SStefano Zampini } 3994dc456d91SStefano Zampini /* local size of new subset */ 3995dc456d91SStefano Zampini n_n = 0; 3996dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 3997dc456d91SStefano Zampini 3998dc456d91SStefano Zampini /* global indexes in layout */ 3999dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4000dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4001dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4002dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4003dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4004dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4005dc456d91SStefano Zampini 4006dc456d91SStefano Zampini /* reduce from leaves to roots */ 4007dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 400864a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 400964a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4010dc456d91SStefano Zampini 4011dc456d91SStefano Zampini /* count indexes in local part of layout */ 4012674ae819SStefano Zampini nlocals = 0; 4013674ae819SStefano Zampini first_index = -1; 4014674ae819SStefano Zampini first_found = PETSC_FALSE; 4015dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4016dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4017674ae819SStefano Zampini first_found = PETSC_TRUE; 4018674ae819SStefano Zampini first_index = i; 4019674ae819SStefano Zampini } 4020dc456d91SStefano Zampini nlocals += root_data[i]; 4021674ae819SStefano Zampini } 4022dc456d91SStefano Zampini 4023dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 40245fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4025dc456d91SStefano Zampini start = 0; 402664a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40275fa240b1SStefano Zampini #else 402864a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40295fa240b1SStefano Zampini start = start-nlocals; 40305fa240b1SStefano Zampini #endif 40315fa240b1SStefano Zampini 4032dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4033dc456d91SStefano Zampini *N_n = start + nlocals; 4034dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4035dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4036674ae819SStefano Zampini } 40375fa240b1SStefano Zampini 40385fa240b1SStefano Zampini /* adapt root data with cumulative */ 4039674ae819SStefano Zampini if (first_found) { 4040dc456d91SStefano Zampini PetscInt old_index; 4041dc456d91SStefano Zampini 4042dc456d91SStefano Zampini root_data[first_index] += start; 4043674ae819SStefano Zampini old_index = first_index; 4044dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4045dc456d91SStefano Zampini if (root_data[i]) { 4046dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4047674ae819SStefano Zampini old_index = i; 4048674ae819SStefano Zampini } 4049674ae819SStefano Zampini } 4050674ae819SStefano Zampini } 4051dc456d91SStefano Zampini 4052dc456d91SStefano Zampini /* from roots to leaves */ 4053dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4054dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4055dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4056dc456d91SStefano Zampini 4057dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4058dc456d91SStefano Zampini if (subset_mult) { 4059dc456d91SStefano Zampini const PetscInt* idxs_mult; 4060dc456d91SStefano Zampini PetscInt cum; 4061dc456d91SStefano Zampini 4062dc456d91SStefano Zampini cum = 0; 4063dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4064dc456d91SStefano Zampini for (i=0;i<n;i++) { 4065dc456d91SStefano Zampini PetscInt j; 4066dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4067674ae819SStefano Zampini } 4068dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4069674ae819SStefano Zampini } else { 4070dc456d91SStefano Zampini for (i=0;i<n;i++) { 4071dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4072674ae819SStefano Zampini } 4073674ae819SStefano Zampini } 4074dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4075dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4076674ae819SStefano Zampini PetscFunctionReturn(0); 4077674ae819SStefano Zampini } 40789a7d3425SStefano Zampini 40799a7d3425SStefano Zampini #undef __FUNCT__ 40809a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 40819a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 40829a7d3425SStefano Zampini { 40839a7d3425SStefano Zampini PetscInt i,j; 40849a7d3425SStefano Zampini PetscScalar *alphas; 40859a7d3425SStefano Zampini PetscErrorCode ierr; 40869a7d3425SStefano Zampini 40879a7d3425SStefano Zampini PetscFunctionBegin; 40889a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4089785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 40909a7d3425SStefano Zampini for (i=0;i<n;i++) { 40919a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 40929a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 40939a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 40949a7d3425SStefano Zampini } 40959a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 40969a7d3425SStefano Zampini PetscFunctionReturn(0); 40979a7d3425SStefano Zampini } 40989a7d3425SStefano Zampini 4099e7931f94SStefano Zampini #undef __FUNCT__ 410070cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 4101b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 4102e7931f94SStefano Zampini { 410352e5ac9dSStefano Zampini IS ranks_send_to; 4104e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4105e7931f94SStefano Zampini PetscMPIInt size,rank,color; 410652e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 410752e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 41083837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 41092b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 4110e7931f94SStefano Zampini PetscSubcomm subcomm; 411152e5ac9dSStefano Zampini PetscErrorCode ierr; 4112a57a6d2fSStefano Zampini 4113e7931f94SStefano Zampini PetscFunctionBegin; 41142b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 41152b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 41162b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 4117e7931f94SStefano Zampini 4118e7931f94SStefano Zampini /* Get info on mapping */ 41193bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 41203bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4121e7931f94SStefano Zampini 4122e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4123785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4124e7931f94SStefano Zampini xadj[0] = 0; 4125e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4126785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4127785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 4128e7931f94SStefano Zampini 41292b510759SStefano Zampini if (threshold) { 4130d023bfaeSStefano Zampini PetscInt xadj_count = 0; 41312b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 4132d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 4133d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4134d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4135d023bfaeSStefano Zampini xadj_count++; 4136e7931f94SStefano Zampini } 4137e7931f94SStefano Zampini } 4138d023bfaeSStefano Zampini xadj[1] = xadj_count; 4139c8587f34SStefano Zampini } else { 4140e7931f94SStefano Zampini if (xadj[1]) { 4141e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 4142e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 4143c8587f34SStefano Zampini } 4144e7931f94SStefano Zampini } 41453bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4146e7931f94SStefano Zampini if (use_square) { 4147e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4148e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 4149e7931f94SStefano Zampini } 4150e7931f94SStefano Zampini } 4151e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4152e7931f94SStefano Zampini 41533837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4154e7931f94SStefano Zampini 4155e7931f94SStefano Zampini /* 4156e7931f94SStefano Zampini Restrict work on active processes only. 4157e7931f94SStefano Zampini */ 4158e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 4159e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 4160e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 41612b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 4162d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4163e7931f94SStefano Zampini if (color) { 4164e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4165e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4166e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4167c8587f34SStefano Zampini } else { 416852e5ac9dSStefano Zampini Mat subdomain_adj; 416952e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 417052e5ac9dSStefano Zampini MatPartitioning partitioner; 417152e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 417252e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 4173b0c7d250SStefano Zampini PetscBool aggregate; 4174b0c7d250SStefano Zampini 4175306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 4176785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 4177e7931f94SStefano Zampini prank = rank; 4178306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 41798002ef2cSStefano Zampini /* 4180e7931f94SStefano Zampini for (i=0;i<size;i++) { 4181e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 4182c8587f34SStefano Zampini } 41838002ef2cSStefano Zampini */ 4184e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4185e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4186c8587f34SStefano Zampini } 4187e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4188b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 4189b0c7d250SStefano Zampini if (aggregate) { 4190b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4191b0c7d250SStefano Zampini PetscMPIInt nrank; 4192b0c7d250SStefano Zampini PetscScalar *vals; 4193b0c7d250SStefano Zampini 4194b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 4195b0c7d250SStefano Zampini lrows = 0; 4196b0c7d250SStefano Zampini if (nrank<redprocs) { 4197b0c7d250SStefano Zampini lrows = size/redprocs; 4198b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4199b0c7d250SStefano Zampini } 42005fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4201b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4202b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4203b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4204b0c7d250SStefano Zampini row = nrank; 4205b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4206b0c7d250SStefano Zampini cols = adjncy; 4207b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4208b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 4209b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 4210b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4211b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 421252e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 421352e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 421452e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4215b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4216b0c7d250SStefano Zampini } else { 4217306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 4218b0c7d250SStefano Zampini } 421922b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 4220e7931f94SStefano Zampini 4221e7931f94SStefano Zampini /* Partition */ 4222306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 4223e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 4224e7931f94SStefano Zampini if (use_vwgt) { 42253837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 4226e7931f94SStefano Zampini v_wgt[0] = local_size; 4227e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 4228c8587f34SStefano Zampini } 422928143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 423028143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 4231e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 4232e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 423322b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 4234e7931f94SStefano Zampini 423552e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 423652e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 423752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 423852e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4239b0c7d250SStefano Zampini if (!redprocs) { 4240b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 424128143c3dSStefano Zampini } else { 4242b0c7d250SStefano Zampini PetscInt idxs[1]; 4243b0c7d250SStefano Zampini PetscMPIInt tag; 4244b0c7d250SStefano Zampini MPI_Request *reqs; 4245b0c7d250SStefano Zampini 4246b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 4247b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 4248b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 4249b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 425028143c3dSStefano Zampini } 4251b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 4252b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4253b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 4254b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 4255e7931f94SStefano Zampini } 425652e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4257e7931f94SStefano Zampini /* clean up */ 4258e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 425952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 4260e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 4261e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 4262e7931f94SStefano Zampini } 4263e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 4264e7931f94SStefano Zampini 4265e7931f94SStefano Zampini /* assemble parallel IS for sends */ 4266e7931f94SStefano Zampini i = 1; 4267e7931f94SStefano Zampini if (color) i=0; 4268e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 4269e7931f94SStefano Zampini /* get back IS */ 4270e7931f94SStefano Zampini *is_sends = ranks_send_to; 4271e7931f94SStefano Zampini PetscFunctionReturn(0); 4272e7931f94SStefano Zampini } 4273e7931f94SStefano Zampini 4274e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 4275e7931f94SStefano Zampini 4276e7931f94SStefano Zampini #undef __FUNCT__ 4277e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 427853a05cb3SStefano 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[]) 4279e7931f94SStefano Zampini { 428070cf5478SStefano Zampini Mat local_mat; 4281e7931f94SStefano Zampini IS is_sends_internal; 42829d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 428328143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 42849d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 4285e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 4286e7931f94SStefano Zampini PetscInt* l2gmap_indices; 4287e7931f94SStefano Zampini const PetscInt* is_indices; 4288e7931f94SStefano Zampini MatType new_local_type; 4289e7931f94SStefano Zampini /* buffers */ 4290e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 429128143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 42929d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 4293e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 4294e7931f94SStefano Zampini /* MPI */ 429528143c3dSStefano Zampini MPI_Comm comm,comm_n; 429628143c3dSStefano Zampini PetscSubcomm subcomm; 4297e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 429828143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 429928143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 430028143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 430128143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 430228143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 4303e7931f94SStefano Zampini PetscErrorCode ierr; 4304e7931f94SStefano Zampini 4305e7931f94SStefano Zampini PetscFunctionBegin; 430628143c3dSStefano Zampini /* TODO: add missing checks */ 430728143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 430828143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 430928143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 431028143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 4311e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 431228143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 4313e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4314e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 4315e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 4316e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 4317e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 431828143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 431970cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 432070cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 432128143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 432270cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 432370cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 432470cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 432570cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 432670cf5478SStefano Zampini } 4327e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4328e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4329e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4330e7931f94SStefano Zampini if (!is_sends) { 433128143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4332b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4333c8587f34SStefano Zampini } else { 4334e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4335e7931f94SStefano Zampini is_sends_internal = is_sends; 4336c8587f34SStefano Zampini } 4337e7931f94SStefano Zampini 4338e7931f94SStefano Zampini /* get comm */ 4339a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4340e7931f94SStefano Zampini 4341e7931f94SStefano Zampini /* compute number of sends */ 4342e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4343e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4344e7931f94SStefano Zampini 4345e7931f94SStefano Zampini /* compute number of receives */ 4346e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4347785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4348e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4349e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4350e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4351e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4352e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4353e7931f94SStefano Zampini 435428143c3dSStefano Zampini /* restrict comm if requested */ 435528143c3dSStefano Zampini subcomm = 0; 435628143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 435728143c3dSStefano Zampini if (restrict_comm) { 4358779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4359779c1cceSStefano Zampini 436028143c3dSStefano Zampini color = 0; 436153a05cb3SStefano Zampini if (restrict_full) { 436253a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 436353a05cb3SStefano Zampini } else { 436453a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 436553a05cb3SStefano Zampini } 436628143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 436728143c3dSStefano Zampini subcommsize = commsize - subcommsize; 436828143c3dSStefano Zampini /* check if reuse has been requested */ 436928143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 437028143c3dSStefano Zampini if (*mat_n) { 437128143c3dSStefano Zampini PetscMPIInt subcommsize2; 437228143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 437328143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 437428143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 437528143c3dSStefano Zampini } else { 437628143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 437728143c3dSStefano Zampini } 437828143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4379779c1cceSStefano Zampini PetscMPIInt rank; 4380779c1cceSStefano Zampini 4381779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 438228143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 438328143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 438428143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4385306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 438628143c3dSStefano Zampini } 438728143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 438828143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 438928143c3dSStefano Zampini } else { 439028143c3dSStefano Zampini comm_n = comm; 439128143c3dSStefano Zampini } 439228143c3dSStefano Zampini 4393e7931f94SStefano Zampini /* prepare send/receive buffers */ 4394785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4395e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4396785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4397e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 439828143c3dSStefano Zampini if (nis) { 4399854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 440028143c3dSStefano Zampini } 4401e7931f94SStefano Zampini 440228143c3dSStefano Zampini /* Get data from local matrices */ 4403e7931f94SStefano Zampini if (!isdense) { 4404a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4405e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4406e7931f94SStefano Zampini /* 4407e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4408e7931f94SStefano Zampini send_buffer_idxs should contain: 4409e7931f94SStefano Zampini - MatType_PRIVATE type 4410e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4411e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4412e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4413e7931f94SStefano Zampini */ 4414e7931f94SStefano Zampini } else { 4415e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 44163bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4417854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4418e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4419e7931f94SStefano Zampini send_buffer_idxs[1] = i; 44203bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4421e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 44223bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4423e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4424e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4425e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4426e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4427c8587f34SStefano Zampini } 4428c8587f34SStefano Zampini } 4429e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 443028143c3dSStefano Zampini /* additional is (if any) */ 443128143c3dSStefano Zampini if (nis) { 443228143c3dSStefano Zampini PetscMPIInt psum; 443328143c3dSStefano Zampini PetscInt j; 443428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 443528143c3dSStefano Zampini PetscInt plen; 443628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 443728143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 443828143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 443928143c3dSStefano Zampini } 4440854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 444128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 444228143c3dSStefano Zampini PetscInt plen; 444328143c3dSStefano Zampini const PetscInt *is_array_idxs; 444428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 444528143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 444628143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 444728143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 444828143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 444928143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 445028143c3dSStefano Zampini } 445128143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 445228143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 445328143c3dSStefano Zampini } 445428143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 445528143c3dSStefano Zampini } 445628143c3dSStefano Zampini 4457e7931f94SStefano Zampini buf_size_idxs = 0; 4458e7931f94SStefano Zampini buf_size_vals = 0; 445928143c3dSStefano Zampini buf_size_idxs_is = 0; 4460e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4461e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4462e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 446328143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4464e7931f94SStefano Zampini } 4465785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4466785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 446795ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4468e7931f94SStefano Zampini 4469e7931f94SStefano Zampini /* get new tags for clean communications */ 4470e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4471e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 447228143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4473e7931f94SStefano Zampini 4474e7931f94SStefano Zampini /* allocate for requests */ 4475785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4476785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 447795ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4478785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4479785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 448095ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4481e7931f94SStefano Zampini 4482e7931f94SStefano Zampini /* communications */ 4483e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4484e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 448528143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4486e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4487e7931f94SStefano Zampini source_dest = onodes[i]; 4488e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4489e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4490e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4491e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 449228143c3dSStefano Zampini if (nis) { 449328143c3dSStefano 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); 449428143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 449528143c3dSStefano Zampini } 4496e7931f94SStefano Zampini } 4497e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4498e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4499e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4500e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 450128143c3dSStefano Zampini if (nis) { 450228143c3dSStefano 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); 450328143c3dSStefano Zampini } 4504e7931f94SStefano Zampini } 4505e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4506e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4507e7931f94SStefano Zampini 4508e7931f94SStefano Zampini /* assemble new l2g map */ 4509e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4510e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45119d30be91SStefano Zampini new_local_rows = 0; 4512e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45139d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4514e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4515e7931f94SStefano Zampini } 45169d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4517e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45189d30be91SStefano Zampini new_local_rows = 0; 4519e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45209d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 45219d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4522e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4523e7931f94SStefano Zampini } 45249d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 45259d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4526e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4527e7931f94SStefano Zampini 4528e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4529e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4530e7931f94SStefano 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) */ 4531e7931f94SStefano Zampini if (n_recvs) { 453228143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4533e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4534e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4535e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4536e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4537e7931f94SStefano Zampini break; 4538e7931f94SStefano Zampini } 4539e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4540e7931f94SStefano Zampini } 4541e7931f94SStefano Zampini switch (new_local_type_private) { 454228143c3dSStefano Zampini case MATDENSE_PRIVATE: 454328143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4544e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4545e7931f94SStefano Zampini bs = 1; 454628143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 454728143c3dSStefano Zampini new_local_type = MATSEQDENSE; 454828143c3dSStefano Zampini bs = 1; 454928143c3dSStefano Zampini } 4550e7931f94SStefano Zampini break; 4551e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4552e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4553e7931f94SStefano Zampini bs = 1; 4554e7931f94SStefano Zampini break; 4555e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4556e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4557e7931f94SStefano Zampini break; 4558e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4559e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4560e7931f94SStefano Zampini break; 4561e7931f94SStefano Zampini default: 45629d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4563e7931f94SStefano Zampini break; 4564e7931f94SStefano Zampini } 456528143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 456628143c3dSStefano Zampini new_local_type = MATSEQDENSE; 456728143c3dSStefano Zampini bs = 1; 4568e7931f94SStefano Zampini } 4569e7931f94SStefano Zampini 457070cf5478SStefano Zampini /* create MATIS object if needed */ 457170cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4572e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4573e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 457470cf5478SStefano Zampini } else { 457570cf5478SStefano Zampini /* it also destroys the local matrices */ 457670cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 457770cf5478SStefano Zampini } 457870cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4579e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 45809d30be91SStefano Zampini 45819d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 45829d30be91SStefano Zampini 45839d30be91SStefano Zampini /* Global to local map of received indices */ 45849d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 45859d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 45869d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 45879d30be91SStefano Zampini 45889d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 45899d30be91SStefano Zampini buf_size_idxs = 0; 45909d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 45919d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 45929d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 45939d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 45949d30be91SStefano Zampini } 45959d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 45969d30be91SStefano Zampini 45979d30be91SStefano Zampini /* set preallocation */ 45989d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 45999d30be91SStefano Zampini if (!newisdense) { 46009d30be91SStefano Zampini PetscInt *new_local_nnz=0; 46019d30be91SStefano Zampini 46029d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 46039d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 46049d30be91SStefano Zampini if (n_recvs) { 46059d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 46069d30be91SStefano Zampini } 46079d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 46089d30be91SStefano Zampini PetscInt j; 46099d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 46109d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 46119d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 46129d30be91SStefano Zampini } 46139d30be91SStefano Zampini } else { 46149d30be91SStefano Zampini /* TODO */ 46159d30be91SStefano Zampini } 46169d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 46179d30be91SStefano Zampini } 46189d30be91SStefano Zampini if (new_local_nnz) { 46199d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 46209d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 46219d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 46229d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46239d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 46249d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46259d30be91SStefano Zampini } else { 46269d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46279d30be91SStefano Zampini } 46289d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 46299d30be91SStefano Zampini } else { 46309d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46319d30be91SStefano Zampini } 4632e7931f94SStefano Zampini 4633e7931f94SStefano Zampini /* set values */ 4634e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 46359d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 4636e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4637e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 4638e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 46399d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 4640e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4641e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4642e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 464328143c3dSStefano Zampini } else { 464428143c3dSStefano Zampini /* TODO */ 4645e7931f94SStefano Zampini } 4646e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4647e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 4648e7931f94SStefano Zampini } 4649e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4650e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 465170cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 465270cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46539d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 46549d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 4655e7931f94SStefano Zampini 4656dfd14d43SStefano Zampini #if 0 465728143c3dSStefano Zampini if (!restrict_comm) { /* check */ 4658e7931f94SStefano Zampini Vec lvec,rvec; 4659e7931f94SStefano Zampini PetscReal infty_error; 4660e7931f94SStefano Zampini 46612a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 4662e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 4663e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 4664e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 466570cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 4666e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4667e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 4668e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 4669e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 4670e7931f94SStefano Zampini } 467128143c3dSStefano Zampini #endif 4672e7931f94SStefano Zampini 467328143c3dSStefano Zampini /* assemble new additional is (if any) */ 467428143c3dSStefano Zampini if (nis) { 467528143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 467628143c3dSStefano Zampini 467728143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4678854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 467928143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 468028143c3dSStefano Zampini psum = 0; 468128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 468228143c3dSStefano Zampini for (j=0;j<nis;j++) { 468328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 468428143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 468528143c3dSStefano Zampini psum += plen; 468628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 468728143c3dSStefano Zampini } 468828143c3dSStefano Zampini } 4689854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 4690854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 469128143c3dSStefano Zampini for (i=1;i<nis;i++) { 469228143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 469328143c3dSStefano Zampini } 469428143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 469528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 469628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 469728143c3dSStefano Zampini for (j=0;j<nis;j++) { 469828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 469928143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 470028143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 470128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 470228143c3dSStefano Zampini } 470328143c3dSStefano Zampini } 470428143c3dSStefano Zampini for (i=0;i<nis;i++) { 470528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 470628143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 470728143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 470828143c3dSStefano Zampini } 470928143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 471028143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 471128143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 471228143c3dSStefano Zampini } 4713e7931f94SStefano Zampini /* free workspace */ 471428143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4715e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4716e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4717e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4718e7931f94SStefano Zampini if (isdense) { 4719e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4720e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4721e7931f94SStefano Zampini } else { 4722e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4723e7931f94SStefano Zampini } 472428143c3dSStefano Zampini if (nis) { 472528143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 472628143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 472728143c3dSStefano Zampini } 4728e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4729e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 473028143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4731e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4732e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 473328143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4734e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4735e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4736e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4737e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4738e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 473928143c3dSStefano Zampini if (nis) { 474028143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 474128143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 474228143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 474328143c3dSStefano Zampini } 474428143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 474528143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 474628143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 474728143c3dSStefano Zampini for (i=0;i<nis;i++) { 474828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 474928143c3dSStefano Zampini } 475053a05cb3SStefano Zampini *mat_n = NULL; 475128143c3dSStefano Zampini } 4752e7931f94SStefano Zampini PetscFunctionReturn(0); 4753e7931f94SStefano Zampini } 4754a57a6d2fSStefano Zampini 475512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4756af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 475712edc857SStefano Zampini 4758c8587f34SStefano Zampini #undef __FUNCT__ 4759c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4760c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4761c8587f34SStefano Zampini { 4762c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4763c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 476420a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 47659881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 476620a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 47676e683305SStefano Zampini IS coarse_is,*isarray; 47686e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 47696e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 4770f9eb5b7dSStefano Zampini PC pc_temp; 4771c8587f34SStefano Zampini PCType coarse_pc_type; 4772c8587f34SStefano Zampini KSPType coarse_ksp_type; 4773f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 47744f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 47756e683305SStefano Zampini Mat t_coarse_mat_is; 47766e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 47776e683305SStefano Zampini PetscMPIInt all_procs; 477874e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 477968457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 478022bc73bbSStefano Zampini PetscScalar *array; 47819881197aSStefano Zampini PetscErrorCode ierr; 4782fdc09c96SStefano Zampini 4783c8587f34SStefano Zampini PetscFunctionBegin; 4784c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 478568457ee5SStefano 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 */ 4786fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 47875a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4788fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4789f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4790f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4791f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4792fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 479351bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 479451bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4795dc4bcba2SStefano Zampini PC pc; 4796dc4bcba2SStefano Zampini PetscBool isbddc; 4797dc4bcba2SStefano Zampini 4798dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4799dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4800dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4801dc4bcba2SStefano Zampini if (isbddc) { 4802dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4803dc4bcba2SStefano Zampini } 4804727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4805fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4806fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4807fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4808f4ddd8eeSStefano Zampini } 4809fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4810fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4811f4ddd8eeSStefano Zampini } 481270cf5478SStefano Zampini /* reset any subassembling information */ 481370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 48146e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 48156e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4816fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4817f4ddd8eeSStefano Zampini } 4818c8587f34SStefano Zampini 48196e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 48202b510759SStefano Zampini im_active = !!(pcis->n); 48212b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 48226e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 48236e683305SStefano Zampini void_procs = all_procs-active_procs; 48246e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 482574e2c79eSStefano Zampini redist = PETSC_FALSE; 482622bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 48276e683305SStefano Zampini csin_ml = PETSC_TRUE; 48286e683305SStefano Zampini ncoarse_ml = void_procs; 4829779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4830779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 48316e683305SStefano Zampini csin_ds = PETSC_TRUE; 483218a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 483318a45a71SStefano Zampini redist = PETSC_TRUE; 483418a45a71SStefano Zampini } else { 48356e683305SStefano Zampini csin_ds = PETSC_TRUE; 4836779c1cceSStefano Zampini ncoarse_ds = active_procs; 4837779c1cceSStefano Zampini redist = PETSC_TRUE; 483818a45a71SStefano Zampini } 48396e683305SStefano Zampini } else { 48406e683305SStefano Zampini csin_ml = PETSC_FALSE; 48416e683305SStefano Zampini ncoarse_ml = all_procs; 48426e683305SStefano Zampini if (void_procs) { 48436e683305SStefano Zampini csin_ds = PETSC_TRUE; 48446e683305SStefano Zampini ncoarse_ds = void_procs; 48456e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 48466e683305SStefano Zampini } else { 4847779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 484874e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 484974e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 485074e2c79eSStefano Zampini redist = PETSC_TRUE; 485174e2c79eSStefano Zampini } else { 48526e683305SStefano Zampini csin_ds = PETSC_FALSE; 48536e683305SStefano Zampini ncoarse_ds = all_procs; 48546e683305SStefano Zampini } 48556e683305SStefano Zampini } 485674e2c79eSStefano Zampini } 48576e683305SStefano Zampini 48586e683305SStefano Zampini /* 48596e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 48606e683305SStefano Zampini - we have not exceeded the number of levels requested 48616e683305SStefano Zampini - we can actually subassemble the active processes 48626e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 48636e683305SStefano Zampini */ 48646e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 48656e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 48666e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 48676e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 48686e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4869f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 48702b510759SStefano Zampini } else { 4871f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4872c8587f34SStefano Zampini } 4873c8587f34SStefano Zampini } 48746e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 48756e683305SStefano Zampini if (multilevel_allowed) { 48766e683305SStefano Zampini ncoarse = ncoarse_ml; 48776e683305SStefano Zampini csin = csin_ml; 487858da7f69SStefano Zampini redist = PETSC_FALSE; 48796e683305SStefano Zampini } else { 48806e683305SStefano Zampini ncoarse = ncoarse_ds; 48816e683305SStefano Zampini csin = csin_ds; 48826e683305SStefano Zampini } 4883e7931f94SStefano Zampini 4884abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4885abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4886abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4887abbbba34SStefano Zampini 4888abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 488922bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 489022bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 489122bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 489222bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4893b1ecc7b1SStefano Zampini #if 0 4894b9b85e73SStefano Zampini { 4895b9b85e73SStefano Zampini PetscViewer viewer; 4896b9b85e73SStefano Zampini char filename[256]; 4897b1ecc7b1SStefano Zampini sprintf(filename,"local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4898b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4899b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4900b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 4901b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4902b9b85e73SStefano Zampini } 4903b9b85e73SStefano Zampini #endif 4904e176bc59SStefano 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); 49056e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 49066e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49076e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4908abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4909abbbba34SStefano Zampini 49106e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 49116e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 49126e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 49136e683305SStefano Zampini const PetscInt *idxs; 49146e683305SStefano Zampini ISLocalToGlobalMapping tmap; 49156e683305SStefano Zampini 49166e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 49170be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 49186e683305SStefano Zampini /* allocate space for temporary storage */ 4919854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4920854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 49216e683305SStefano Zampini /* allocate for IS array */ 49226e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 49236e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 49246e683305SStefano Zampini nis = nisdofs + nisneu; 4925854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 49266e683305SStefano Zampini /* dofs splitting */ 49276e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 49286e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 49296e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 49306e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49316e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49326e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49336e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 49346e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 49356e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 49366e683305SStefano Zampini } 49376e683305SStefano Zampini /* neumann boundaries */ 49386e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 49396e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 49406e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 49416e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49426e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49436e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49446e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 49456e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 49466e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 49476e683305SStefano Zampini } 49486e683305SStefano Zampini /* free memory */ 49496e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 49506e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 49516e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 49526e683305SStefano Zampini } else { 49536e683305SStefano Zampini nis = 0; 49546e683305SStefano Zampini nisdofs = 0; 49556e683305SStefano Zampini nisneu = 0; 49566e683305SStefano Zampini isarray = NULL; 49576e683305SStefano Zampini } 49586e683305SStefano Zampini /* destroy no longer needed map */ 49596e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 49606e683305SStefano Zampini 49616e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 49626e683305SStefano Zampini coarse_mat_is = NULL; 49636e683305SStefano Zampini if (csin) { 49646e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 496574e2c79eSStefano Zampini if (redist) { 496674e2c79eSStefano Zampini PetscMPIInt rank; 4967779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 496874e2c79eSStefano Zampini 496974e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 497058da7f69SStefano Zampini spc = active_procs/ncoarse; 497158da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 4972779c1cceSStefano Zampini if (im_active) { 4973779c1cceSStefano Zampini destsize = 1; 497474e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 497574e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 497674e2c79eSStefano Zampini } else { 497774e2c79eSStefano Zampini dest[0] = rank/(spc+1); 497874e2c79eSStefano Zampini } 497974e2c79eSStefano Zampini } else { 4980779c1cceSStefano Zampini destsize = 0; 49816e683305SStefano Zampini } 4982779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4983779c1cceSStefano Zampini } else if (csin_type_simple) { 49846e683305SStefano Zampini PetscMPIInt rank; 49856e683305SStefano Zampini PetscInt issize,isidx; 4986779c1cceSStefano Zampini 49876e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 49886e683305SStefano Zampini if (im_active) { 49896e683305SStefano Zampini issize = 1; 49906e683305SStefano Zampini isidx = (PetscInt)rank; 49916e683305SStefano Zampini } else { 49926e683305SStefano Zampini issize = 0; 49936e683305SStefano Zampini isidx = -1; 49946e683305SStefano Zampini } 49956e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4996779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 4997b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 49986e683305SStefano Zampini } 4999779c1cceSStefano Zampini 5000779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 5001779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 5002779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 5003779c1cceSStefano Zampini PetscInt *coarse_candidates; 5004779c1cceSStefano Zampini const PetscInt* tisindices; 5005779c1cceSStefano Zampini 5006779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 5007779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 5008779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5009779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 5010779c1cceSStefano Zampini if (!coarse_candidates[i]) { 5011779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 5012779c1cceSStefano Zampini } 5013779c1cceSStefano Zampini } 5014779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 5015779c1cceSStefano Zampini 5016779c1cceSStefano Zampini 50176e683305SStefano Zampini if (pcbddc->dbg_flag) { 50186e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50196e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 50206e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50216e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 5022779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 50236e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 50246e683305SStefano Zampini } 50256e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 50266e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50276e683305SStefano Zampini } 50286e683305SStefano Zampini /* shift the pattern on coarse candidates */ 50296e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 50306e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 5031854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 50326e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 50336e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 50346e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 50356e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 50366e683305SStefano Zampini } 50376e683305SStefano Zampini if (pcbddc->dbg_flag) { 50386e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50396e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 50406e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50416e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50426e683305SStefano Zampini } 5043779c1cceSStefano Zampini } 50446e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 504553a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 504653a05cb3SStefano 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); 504753a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 504853a05cb3SStefano 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); 504953a05cb3SStefano Zampini } 50506e683305SStefano Zampini } else { 50516e683305SStefano Zampini if (pcbddc->dbg_flag) { 50526e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50536e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 50546e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50556e683305SStefano Zampini } 50566e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 50576e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 50586e683305SStefano Zampini } 50596e683305SStefano Zampini 50606e683305SStefano Zampini /* create local to global scatters for coarse problem */ 506168457ee5SStefano Zampini if (compute_vecs) { 50626e683305SStefano Zampini PetscInt lrows; 50636e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 50646e683305SStefano Zampini if (coarse_mat_is) { 50656e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 50666e683305SStefano Zampini } else { 50676e683305SStefano Zampini lrows = 0; 50686e683305SStefano Zampini } 50696e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 50706e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 50716e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 50726e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 50736e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 50746e683305SStefano Zampini } 50756e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 50766e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 5077c8587f34SStefano Zampini 5078f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5079f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5080f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5081f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5082f9eb5b7dSStefano Zampini } else { 5083f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5084f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5085c8587f34SStefano Zampini } 5086c8587f34SStefano Zampini 50876e683305SStefano Zampini /* print some info if requested */ 50886e683305SStefano Zampini if (pcbddc->dbg_flag) { 50896e683305SStefano Zampini if (!multilevel_allowed) { 50906e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50916e683305SStefano Zampini if (multilevel_requested) { 50926e683305SStefano 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); 50936e683305SStefano Zampini } else if (pcbddc->max_levels) { 50946e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 50956e683305SStefano Zampini } 50966e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50976e683305SStefano Zampini } 50986e683305SStefano Zampini } 50996e683305SStefano Zampini 5100f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 51016e683305SStefano Zampini if (coarse_mat_is) { 51026e683305SStefano Zampini MatReuse coarse_mat_reuse; 51036a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 51046e683305SStefano Zampini if (pcbddc->dbg_flag) { 51056e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 51066e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 51076e683305SStefano Zampini } 5108f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5109312be037SStefano Zampini char prefix[256],str_level[16]; 5110e604994aSStefano Zampini size_t len; 51116e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5112422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5113c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5114f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 51155f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 5116c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 51176e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5118c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5119c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5120e604994aSStefano Zampini /* prefix */ 5121e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5122e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5123e604994aSStefano Zampini if (!pcbddc->current_level) { 5124e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5125e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5126c8587f34SStefano Zampini } else { 5127e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5128312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5129312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 513034d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5131312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5132e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5133e604994aSStefano Zampini } 5134e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 51353e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 51363e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 51373e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 51383e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5139f9eb5b7dSStefano Zampini /* allow user customization */ 5140f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 51413e3c6dadSStefano Zampini } 51423e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 514351bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 51443e3c6dadSStefano Zampini if (nisdofs) { 51453e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 51463e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 51473e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 51483e3c6dadSStefano Zampini } 51493e3c6dadSStefano Zampini } 51503e3c6dadSStefano Zampini if (nisneu) { 51513e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 51523e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5153312be037SStefano Zampini } 5154f9eb5b7dSStefano Zampini 5155f9eb5b7dSStefano Zampini /* get some info after set from options */ 5156f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5157f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 51584f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 51596e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5160f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5161f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5162f9eb5b7dSStefano Zampini } 516339f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 51644f3a063dSStefano Zampini if (isredundant) { 51654f3a063dSStefano Zampini KSP inner_ksp; 51664f3a063dSStefano Zampini PC inner_pc; 51674f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 51684f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 51694f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 51704f3a063dSStefano Zampini } 5171f9eb5b7dSStefano Zampini 5172f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 5173fa7f1dd8SStefano Zampini if (coarse_reuse) { 517481d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 5175fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 51766e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 5177fa7f1dd8SStefano Zampini } else { 51786e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 5179fa7f1dd8SStefano Zampini } 5180c8587f34SStefano Zampini if (isbddc || isnn) { 518122bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 518270cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 5183b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 518422b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 51856e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 51866e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 51876e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 51886e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 518922b6e8a2SStefano Zampini } 519070cf5478SStefano Zampini } 519153a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 519270cf5478SStefano Zampini } else { 519322bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 519422bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 519522bc73bbSStefano Zampini } 519622bc73bbSStefano Zampini } else { 51972e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 5198c8587f34SStefano Zampini } 5199c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 5200c8587f34SStefano Zampini 52013301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 52025a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 52033301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 52043301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 52053301b35fSStefano Zampini } 52063301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 52073301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 52083301b35fSStefano Zampini } 52093301b35fSStefano Zampini if (pc->pmat->spd_set) { 52103301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 52113301b35fSStefano Zampini } 52126e683305SStefano Zampini /* set operators */ 52135f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 52146e683305SStefano Zampini if (pcbddc->dbg_flag) { 52156e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 52166e683305SStefano Zampini } 52176e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 52186e683305SStefano Zampini coarse_mat = 0; 52196e683305SStefano Zampini } 52206e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5221b1ecc7b1SStefano Zampini #if 0 5222b9b85e73SStefano Zampini { 5223b9b85e73SStefano Zampini PetscViewer viewer; 5224b9b85e73SStefano Zampini char filename[256]; 5225b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5226b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 5227b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5228b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5229b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5230b9b85e73SStefano Zampini } 5231b9b85e73SStefano Zampini #endif 5232c8587f34SStefano Zampini 5233c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 5234298c0119SStefano Zampini #if 0 5235c8587f34SStefano Zampini if (pcbddc->NullSpace) { 5236c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 523798a51de6SStefano Zampini } 5238298c0119SStefano Zampini #endif 5239b0f5fe93SStefano Zampini /* hack */ 524098a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 524198a51de6SStefano Zampini Vec crhs,csol; 524204708bb6SStefano Zampini 5243f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 5244f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 5245f347579bSStefano Zampini if (!csol) { 52462a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 5247f9eb5b7dSStefano Zampini } 5248f347579bSStefano Zampini if (!crhs) { 52492a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 5250f347579bSStefano Zampini } 5251b0f5fe93SStefano Zampini } 5252b0f5fe93SStefano Zampini 5253b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 5254b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 5255b0f5fe93SStefano Zampini 5256b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 52574f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 52584f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 52594f1b2e48SStefano Zampini } 5260b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 5261b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 5262b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5263b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5264b0f5fe93SStefano Zampini if (coarse_mat) { 5265b0f5fe93SStefano Zampini Vec nullv; 5266b0f5fe93SStefano Zampini PetscScalar *array,*array2; 5267b0f5fe93SStefano Zampini PetscInt nl; 5268b0f5fe93SStefano Zampini 5269b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 5270b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 5271b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5272b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 5273b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 5274b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 5275b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5276b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 5277b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 5278b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 5279b0f5fe93SStefano Zampini } 5280b0f5fe93SStefano Zampini } 5281b0f5fe93SStefano Zampini 5282b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 5283b0f5fe93SStefano Zampini PetscBool ispreonly; 5284b0f5fe93SStefano Zampini 5285b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5286b0f5fe93SStefano Zampini PetscBool isnull; 5287b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 5288b0f5fe93SStefano Zampini if (isnull) { 5289b0f5fe93SStefano Zampini if (isbddc) { 5290b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 5291b0f5fe93SStefano Zampini } else { 5292b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 5293b0f5fe93SStefano Zampini } 5294b0f5fe93SStefano Zampini } else { 5295b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5296b0f5fe93SStefano Zampini } 5297b0f5fe93SStefano Zampini } 5298b0f5fe93SStefano Zampini /* setup coarse ksp */ 5299b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 5300cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 5301cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 53026e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 5303c8587f34SStefano Zampini KSP check_ksp; 53042b510759SStefano Zampini KSPType check_ksp_type; 5305c8587f34SStefano Zampini PC check_pc; 53066e683305SStefano Zampini Vec check_vec,coarse_vec; 53076a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 53082b510759SStefano Zampini PetscInt its; 53096e683305SStefano Zampini PetscBool compute_eigs; 53106e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 53116e683305SStefano Zampini PetscInt neigs; 53128e185a42SStefano Zampini const char *prefix; 5313c8587f34SStefano Zampini 53142b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 53156e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 5316422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 531723ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5318f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 53192b510759SStefano Zampini if (ispreonly) { 53202b510759SStefano Zampini check_ksp_type = KSPPREONLY; 53216e683305SStefano Zampini compute_eigs = PETSC_FALSE; 53222b510759SStefano Zampini } else { 5323cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 53246e683305SStefano Zampini compute_eigs = PETSC_TRUE; 5325c8587f34SStefano Zampini } 5326c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 53276e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 53286e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 53296e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5330a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5331a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5332a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5333a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5334c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5335c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5336c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5337c8587f34SStefano Zampini /* create random vec */ 53386e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 53396e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5340c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5341c8587f34SStefano Zampini if (CoarseNullSpace) { 5342c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5343c8587f34SStefano Zampini } 53446e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5345c8587f34SStefano Zampini /* solve coarse problem */ 53466e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5347c8587f34SStefano Zampini if (CoarseNullSpace) { 53486e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5349c8587f34SStefano Zampini } 5350cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 53516e683305SStefano Zampini if (compute_eigs) { 5352854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5353854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 53546e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 53556e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 53566e683305SStefano Zampini lambda_min = eigs_r[0]; 53576e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 53586e683305SStefano Zampini if (lambda_max>lambda_min) { 5359cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5360cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5361cbcc2c2aSStefano Zampini } 5362c8587f34SStefano Zampini } 5363c8587f34SStefano Zampini } 5364cbcc2c2aSStefano Zampini 5365c8587f34SStefano Zampini /* check coarse problem residual error */ 53666e683305SStefano Zampini if (pcbddc->dbg_flag) { 53676e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 53686e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 53696e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5370c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 53716e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 53726e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5373c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5374779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 53756e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 53766e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 53776e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 53786e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5379b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5380b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5381b0f5fe93SStefano Zampini } 53826e683305SStefano Zampini if (compute_eigs) { 53836e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5384deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5385c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 53866e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 53876e683305SStefano 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); 53886e683305SStefano Zampini for (i=0;i<neigs;i++) { 53896e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5390c8587f34SStefano Zampini } 53916e683305SStefano Zampini } 53926e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 53936e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 53946e683305SStefano Zampini } 5395c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 53966e683305SStefano Zampini if (compute_eigs) { 53976e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 53986e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5399c8587f34SStefano Zampini } 54006e683305SStefano Zampini } 54016e683305SStefano Zampini } 5402cbcc2c2aSStefano Zampini /* print additional info */ 5403cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 54046e683305SStefano Zampini /* waits until all processes reaches this point */ 54056e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5406cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5407cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5408cbcc2c2aSStefano Zampini } 5409cbcc2c2aSStefano Zampini 54102b510759SStefano Zampini /* free memory */ 5411c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5412fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5413c8587f34SStefano Zampini PetscFunctionReturn(0); 5414c8587f34SStefano Zampini } 5415674ae819SStefano Zampini 5416f34684f1SStefano Zampini #undef __FUNCT__ 5417f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5418f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5419f34684f1SStefano Zampini { 5420f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5421f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5422f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5423dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5424dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 542573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5426dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5427f34684f1SStefano Zampini PetscErrorCode ierr; 5428f34684f1SStefano Zampini 5429f34684f1SStefano Zampini PetscFunctionBegin; 5430f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 54310e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 54320e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5433727cdba6SStefano Zampini } 5434dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 54353bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5436dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5437dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5438dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5439dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5440dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5441dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 54420e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 54430e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 54440e6343abSStefano Zampini } 5445dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5446dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5447dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5448dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5449dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5450f34684f1SStefano Zampini 5451f34684f1SStefano Zampini /* check numbering */ 5452f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5453019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5454dc456d91SStefano Zampini PetscInt i; 5455b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5456f34684f1SStefano Zampini 5457f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5458f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5459f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 54600fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 5461019a44ceSStefano Zampini /* counter */ 5462019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5463019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5464019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5465019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5466019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5467019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5468019a44ceSStefano Zampini 5469f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5470f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5471727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5472f34684f1SStefano Zampini } 5473f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5474f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5475f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5476e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5477e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5478e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5479e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5480f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5481019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5482f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5483019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 548475c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 548575c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5486b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5487019a44ceSStefano 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); 5488f34684f1SStefano Zampini } 5489f34684f1SStefano Zampini } 5490019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5491b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5492f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5493f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5494f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5495f34684f1SStefano Zampini } 5496f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5497f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5498e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5499e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5500f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5501f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5502b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5503ca8b9ea9SStefano Zampini PetscInt *gidxs; 5504ca8b9ea9SStefano Zampini 5505ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 55063bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5507f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5508f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5509f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5510f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 55114bc2dc4bSStefano 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); 5512f34684f1SStefano Zampini } 5513f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5514ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5515f34684f1SStefano Zampini } 5516f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5517302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5518f34684f1SStefano Zampini } 55198bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5520f34684f1SStefano Zampini /* get back data */ 5521f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5522f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5523674ae819SStefano Zampini PetscFunctionReturn(0); 5524674ae819SStefano Zampini } 5525674ae819SStefano Zampini 5526e456f2a8SStefano Zampini #undef __FUNCT__ 5527e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5528a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5529e456f2a8SStefano Zampini { 5530e456f2a8SStefano Zampini IS localis_t; 5531a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5532e456f2a8SStefano Zampini PetscScalar *vals; 5533e456f2a8SStefano Zampini PetscErrorCode ierr; 5534e456f2a8SStefano Zampini 5535e456f2a8SStefano Zampini PetscFunctionBegin; 5536a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5537e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5538854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5539e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5540e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5541a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5542a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 55431035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5544a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 55451035eff8SStefano Zampini } 5546a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5547e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5548e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5549a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5550a7dc3881SStefano Zampini /* now compute set in local ordering */ 5551a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5552a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5553a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5554a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5555a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5556ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5557e456f2a8SStefano Zampini lsize++; 5558e456f2a8SStefano Zampini } 5559e456f2a8SStefano Zampini } 5560854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5561a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5562ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5563e456f2a8SStefano Zampini idxs[lsize++] = i; 5564e456f2a8SStefano Zampini } 5565e456f2a8SStefano Zampini } 5566a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5567a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5568e456f2a8SStefano Zampini *localis = localis_t; 5569e456f2a8SStefano Zampini PetscFunctionReturn(0); 5570e456f2a8SStefano Zampini } 5571906d46d4SStefano Zampini 5572906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5573906d46d4SStefano Zampini #undef __FUNCT__ 5574906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5575906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5576906d46d4SStefano Zampini { 5577906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5578906d46d4SStefano Zampini PetscErrorCode ierr; 5579906d46d4SStefano Zampini 5580906d46d4SStefano Zampini PetscFunctionBegin; 5581906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5582906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5583906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5584906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5585906d46d4SStefano Zampini PetscFunctionReturn(0); 5586906d46d4SStefano Zampini } 5587906d46d4SStefano Zampini 5588906d46d4SStefano Zampini #undef __FUNCT__ 5589906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5590906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5591906d46d4SStefano Zampini { 5592906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5593906d46d4SStefano Zampini PetscErrorCode ierr; 5594906d46d4SStefano Zampini 5595906d46d4SStefano Zampini PetscFunctionBegin; 5596906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5597906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5598906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5599906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5600906d46d4SStefano Zampini PetscFunctionReturn(0); 5601906d46d4SStefano Zampini } 5602b96c3477SStefano Zampini 5603b96c3477SStefano Zampini #undef __FUNCT__ 5604b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 560508122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5606b96c3477SStefano Zampini { 5607a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5608b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5609b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5610a64f4aa4SStefano Zampini Mat S_j; 5611b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 5612b96c3477SStefano Zampini PetscBool free_used_adj; 5613b96c3477SStefano Zampini PetscErrorCode ierr; 5614b96c3477SStefano Zampini 5615b96c3477SStefano Zampini PetscFunctionBegin; 5616b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 5617b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 561808122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 5619b96c3477SStefano Zampini used_xadj = NULL; 5620b96c3477SStefano Zampini used_adjncy = NULL; 5621b96c3477SStefano Zampini } else { 562208122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 562308122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 562408122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 562508122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 5626b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 5627b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 5628b96c3477SStefano Zampini } else { 56292fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 5630b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 5631b96c3477SStefano Zampini PetscInt nvtxs; 5632b96c3477SStefano Zampini 56332fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 56342fffb893SStefano Zampini if (flg_row) { 5635b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 5636b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 5637b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 5638b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 56392fffb893SStefano Zampini } else { 56402fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 56412fffb893SStefano Zampini used_xadj = NULL; 56422fffb893SStefano Zampini used_adjncy = NULL; 56432fffb893SStefano Zampini } 56442fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 5645b96c3477SStefano Zampini } 5646b96c3477SStefano Zampini } 5647d5574798SStefano Zampini 5648d5574798SStefano Zampini /* setup sub_schurs data */ 5649a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5650a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 5651a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 5652a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 565306a4e24aSStefano 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); 5654a64f4aa4SStefano Zampini } else { 56556816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 565604708bb6SStefano Zampini PetscBool isseqaij; 56575feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 56585feab87aSStefano Zampini PetscInt n_vertices; 56595feab87aSStefano Zampini 56605feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 56612034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 56625feab87aSStefano Zampini } 566304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 566404708bb6SStefano Zampini if (!isseqaij) { 566504708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 566604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 566704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 566804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 566904708bb6SStefano Zampini } else { 567004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 567104708bb6SStefano Zampini } 567204708bb6SStefano Zampini } 567306a4e24aSStefano 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); 5674a64f4aa4SStefano Zampini } 5675a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5676b96c3477SStefano Zampini 5677b96c3477SStefano Zampini /* free adjacency */ 5678b96c3477SStefano Zampini if (free_used_adj) { 5679b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 5680b96c3477SStefano Zampini } 5681b96c3477SStefano Zampini PetscFunctionReturn(0); 5682b96c3477SStefano Zampini } 5683b96c3477SStefano Zampini 5684b96c3477SStefano Zampini #undef __FUNCT__ 5685b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 568608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 5687b96c3477SStefano Zampini { 5688b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5689b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5690b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5691b96c3477SStefano Zampini PCBDDCGraph graph; 5692b96c3477SStefano Zampini PetscErrorCode ierr; 5693b96c3477SStefano Zampini 5694b96c3477SStefano Zampini PetscFunctionBegin; 5695b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 569608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 56973301b35fSStefano Zampini IS verticesIS,verticescomm; 56983301b35fSStefano Zampini PetscInt vsize,*idxs; 5699b96c3477SStefano Zampini 5700b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 57013301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 57023301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57033301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 57043301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57053301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 5706b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 57077fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 57083301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 57093301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 5710b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5711b96c3477SStefano Zampini /* 5712b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 5713b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5714b96c3477SStefano Zampini } 5715b96c3477SStefano Zampini */ 5716b96c3477SStefano Zampini } else { 5717b96c3477SStefano Zampini graph = pcbddc->mat_graph; 5718b96c3477SStefano Zampini } 5719b96c3477SStefano Zampini 5720b96c3477SStefano Zampini /* sub_schurs init */ 5721a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 5722a64f4aa4SStefano Zampini 5723b96c3477SStefano Zampini /* free graph struct */ 572408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 5725b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 5726b96c3477SStefano Zampini } 5727b96c3477SStefano Zampini PetscFunctionReturn(0); 5728b96c3477SStefano Zampini } 5729fa34dd3eSStefano Zampini 5730fa34dd3eSStefano Zampini #undef __FUNCT__ 5731fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 5732fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 5733fa34dd3eSStefano Zampini { 5734fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5735fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5736fa34dd3eSStefano Zampini PetscErrorCode ierr; 5737fa34dd3eSStefano Zampini 5738fa34dd3eSStefano Zampini PetscFunctionBegin; 5739fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 5740fa34dd3eSStefano Zampini IS zerodiag = NULL; 57414f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 5742fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 57434f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 574475c01103SStefano Zampini PetscReal norm; 5745fa34dd3eSStefano Zampini PetscInt i; 5746fa34dd3eSStefano Zampini 5747fa34dd3eSStefano Zampini /* B0 and B0_B */ 5748fa34dd3eSStefano Zampini if (zerodiag) { 5749fa34dd3eSStefano Zampini IS dummy; 5750fa34dd3eSStefano Zampini 57514f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 57524f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 5753fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 5754fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 5755fa34dd3eSStefano Zampini } 5756fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 5757fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 5758fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 5759fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5760fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5761fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5762fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5763fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 5764fa34dd3eSStefano Zampini /* S_j */ 5765fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5766fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 5767fa34dd3eSStefano Zampini 5768fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 5769fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 5770fa34dd3eSStefano Zampini /* continuous in primal space */ 5771fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 5772fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5773fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5774fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 57754f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 57764f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 5777fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5778fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5779fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5780fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5781fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5782fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5783fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 5784fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 5785fa34dd3eSStefano Zampini 5786fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 5787fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 5788fa34dd3eSStefano Zampini /* local with Schur */ 5789fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 5790fa34dd3eSStefano Zampini if (zerodiag) { 5791fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 57924f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 5793fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5794fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5795fa34dd3eSStefano Zampini } 5796fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 5797fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5798fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5799fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5800fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5801fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 5802fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5803fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5804fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 5805fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5806fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5807fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5808fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5809fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5810fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 5811fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 5812fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5813fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5814fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5815fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5816fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5817fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5818fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 5819fa34dd3eSStefano Zampini if (zerodiag) { 5820fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 5821fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 58224f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 5823fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5824fa34dd3eSStefano Zampini } 5825fa34dd3eSStefano Zampini /* BDDC */ 5826fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 5827fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 5828fa34dd3eSStefano Zampini 5829fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 5830fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 5831fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 5832fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 58334f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 58344f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 5835fa34dd3eSStefano Zampini } 58364f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 5837fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 5838fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 5839fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 5840fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5841fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 5842fa34dd3eSStefano Zampini } 5843fa34dd3eSStefano Zampini PetscFunctionReturn(0); 5844fa34dd3eSStefano Zampini } 5845