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; 2569f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 2579f47a83aSStefano 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); 4289f47a83aSStefano 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); 978*30368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 979674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 980674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 981785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 982674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 983f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 984f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 985785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 98663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 98763602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 988674ae819SStefano Zampini PetscFunctionReturn(0); 989674ae819SStefano Zampini } 990674ae819SStefano Zampini 991674ae819SStefano Zampini #undef __FUNCT__ 992674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 993674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 994674ae819SStefano Zampini { 995674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9964f1b2e48SStefano Zampini PetscInt i; 997674ae819SStefano Zampini PetscErrorCode ierr; 998674ae819SStefano Zampini 999674ae819SStefano Zampini PetscFunctionBegin; 1000b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1001674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 1002674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1003674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 10044f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 10054f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 10064f1b2e48SStefano Zampini } 10074f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1008b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1009674ae819SStefano Zampini PetscFunctionReturn(0); 1010674ae819SStefano Zampini } 1011674ae819SStefano Zampini 1012674ae819SStefano Zampini #undef __FUNCT__ 1013674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1014674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1015674ae819SStefano Zampini { 1016674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 101706656605SStefano Zampini PetscScalar *array; 1018674ae819SStefano Zampini PetscErrorCode ierr; 1019674ae819SStefano Zampini 1020674ae819SStefano Zampini PetscFunctionBegin; 1021674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 102258da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 102306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 102406656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 102558da7f69SStefano Zampini } 1026674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1027674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 102815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 102915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1030674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1031674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1032674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 103306656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1034674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1035674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10368ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1037674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1038674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1039674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1040f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1041f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1042f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1043f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1044727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 10450e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1046f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 104770cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 10486e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 104981d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 10500369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 10518b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10524f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10534f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 10548b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 10554f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1056674ae819SStefano Zampini PetscFunctionReturn(0); 1057674ae819SStefano Zampini } 1058674ae819SStefano Zampini 1059674ae819SStefano Zampini #undef __FUNCT__ 1060f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1061f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 10626bfb1811SStefano Zampini { 10636bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10646bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 10656bfb1811SStefano Zampini VecType impVecType; 10664f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 10676bfb1811SStefano Zampini PetscErrorCode ierr; 10686bfb1811SStefano Zampini 10696bfb1811SStefano Zampini PetscFunctionBegin; 1070f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 1071019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1072f4ddd8eeSStefano Zampini } 1073e7b262bdSStefano Zampini /* get sizes */ 10744f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1075b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 10766bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1077e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1078e7b262bdSStefano Zampini /* R nodes */ 1079e7b262bdSStefano Zampini old_size = -1; 1080e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1081e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1082e7b262bdSStefano Zampini } 1083e7b262bdSStefano Zampini if (n_R != old_size) { 1084e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1085e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10866bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 10876bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 10886bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 10896bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1090e7b262bdSStefano Zampini } 1091e7b262bdSStefano Zampini /* local primal dofs */ 1092e7b262bdSStefano Zampini old_size = -1; 1093e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1094e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1095e7b262bdSStefano Zampini } 1096e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1097e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 109883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1099e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 11006bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1101e7b262bdSStefano Zampini } 1102e7b262bdSStefano Zampini /* local explicit constraints */ 1103e7b262bdSStefano Zampini old_size = -1; 1104e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1105e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1106e7b262bdSStefano Zampini } 1107e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1108e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 110983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 111083b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 111183b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 111283b7ccabSStefano Zampini } 11136bfb1811SStefano Zampini PetscFunctionReturn(0); 11146bfb1811SStefano Zampini } 11156bfb1811SStefano Zampini 11166bfb1811SStefano Zampini #undef __FUNCT__ 111747f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 111847f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 111988ebb749SStefano Zampini { 112025084f0cSStefano Zampini PetscErrorCode ierr; 112125084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 112288ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 112388ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1124d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 112525084f0cSStefano Zampini /* submatrices of local problem */ 112680677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 1127019a44ceSStefano Zampini /* submatrices of benign trick */ 1128d16cbb6bSStefano Zampini Mat B0_V = NULL; 112906656605SStefano Zampini /* submatrices of local coarse problem */ 113006656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 113125084f0cSStefano Zampini /* working matrices */ 113206656605SStefano Zampini Mat C_CR; 113325084f0cSStefano Zampini /* additional working stuff */ 113406656605SStefano Zampini PC pc_R; 11354f1b2e48SStefano Zampini Mat F; 113606656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 113706656605SStefano Zampini 113825084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 113906656605SStefano Zampini PetscScalar *work; 114006656605SStefano Zampini PetscInt *idx_V_B; 11414f1b2e48SStefano Zampini PetscInt n,n_vertices,n_constraints,*p0_lidx_I; 114206656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1143b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 114445a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 114588ebb749SStefano Zampini MatType impMatType; 114625084f0cSStefano Zampini /* some shortcuts to scalars */ 114706656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 114888ebb749SStefano Zampini 114988ebb749SStefano Zampini PetscFunctionBegin; 1150b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 11514f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 115288ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 1153b371cd4fSStefano Zampini n_B = pcis->n_B; 1154b371cd4fSStefano Zampini n_D = pcis->n - n_B; 115588ebb749SStefano Zampini n_R = pcis->n - n_vertices; 115688ebb749SStefano Zampini 115788ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 115888ebb749SStefano Zampini impMatType = MATSEQDENSE; 115988ebb749SStefano Zampini 116088ebb749SStefano Zampini /* vertices in boundary numbering */ 1161785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 11620e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 116388ebb749SStefano Zampini if (i != n_vertices) { 116422d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 116588ebb749SStefano Zampini } 116688ebb749SStefano Zampini 116706656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1168019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 116906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 117006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 117106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 117206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 117306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 117406656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 117506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 117606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 117706656605SStefano Zampini 117806656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 117906656605SStefano Zampini /* allocate workspace */ 118006656605SStefano Zampini n = 0; 118106656605SStefano Zampini if (n_constraints) { 118206656605SStefano Zampini n += n_R*n_constraints; 118306656605SStefano Zampini } 118406656605SStefano Zampini if (n_vertices) { 118506656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 118680677318SStefano Zampini n = PetscMax((n_R+n_B)*n_vertices,n); 118706656605SStefano Zampini } 11883301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 118906656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 119006656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 119106656605SStefano Zampini } 119206656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 119306656605SStefano Zampini 119406656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 119506656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 119606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 119706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 119806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 119906656605SStefano Zampini if (isLU || isILU || isCHOL) { 120006656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1201d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 1202d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1203d62866d3SStefano Zampini MatFactorType type; 1204d62866d3SStefano Zampini 12056816873aSStefano Zampini F = reuse_mumps->F; 12066816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1207d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 120806656605SStefano Zampini } else { 120906656605SStefano Zampini F = NULL; 121006656605SStefano Zampini } 121106656605SStefano Zampini 121288ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 121388ebb749SStefano Zampini if (n_constraints) { 121406656605SStefano Zampini Mat M1,M2,M3; 121580677318SStefano Zampini Mat auxmat; 121606656605SStefano Zampini IS is_aux; 121780677318SStefano Zampini PetscScalar *array,*array2; 121806656605SStefano Zampini 1219f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 122080677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 122188ebb749SStefano Zampini 122225084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 122325084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 12248ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 122580677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 122688ebb749SStefano Zampini 122780677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 122880677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 122906656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 123088ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 123106656605SStefano Zampini const PetscScalar *row_cmat_values; 123206656605SStefano Zampini const PetscInt *row_cmat_indices; 123306656605SStefano Zampini PetscInt size_of_constraint,j; 123488ebb749SStefano Zampini 123506656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 123606656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 123706656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 123806656605SStefano Zampini } 123906656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 124006656605SStefano Zampini } 124180677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 124206656605SStefano Zampini if (F) { 124306656605SStefano Zampini Mat B; 124406656605SStefano Zampini 124506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 124680677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 124706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 124806656605SStefano Zampini } else { 124980677318SStefano Zampini PetscScalar *marr; 125080677318SStefano Zampini 125180677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 125206656605SStefano Zampini for (i=0;i<n_constraints;i++) { 125306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 125480677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*n_R);CHKERRQ(ierr); 125506656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 125606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 125706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 125806656605SStefano Zampini } 125980677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 126006656605SStefano Zampini } 126180677318SStefano Zampini if (!pcbddc->switch_static) { 126280677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 126380677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 126480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 126580677318SStefano Zampini for (i=0;i<n_constraints;i++) { 126680677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*n_R);CHKERRQ(ierr); 126780677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 126880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 127080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 127180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 127280677318SStefano Zampini } 127380677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 127480677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 127580677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 127680677318SStefano Zampini } else { 127780677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 127880677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 127925084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 128080677318SStefano Zampini } 128180677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 128280677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 128380677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 128406656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 128506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 128680677318SStefano Zampini if (isCHOL) { 128780677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 128880677318SStefano Zampini } else { 128925084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 129080677318SStefano Zampini } 129180677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 129206656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 129325084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 129425084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 129525084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 129680677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 129780677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 129880677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 129906656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 130006656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1301f4ddd8eeSStefano Zampini } 130288ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 13034f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1304d16cbb6bSStefano Zampini IS dummy; 1305d16cbb6bSStefano Zampini Mat B0_R; 1306d16cbb6bSStefano Zampini PetscReal norm; 1307d16cbb6bSStefano Zampini 13084f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13094f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1310d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1311d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1312d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1313d16cbb6bSStefano Zampini } 1314d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1315d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1316d16cbb6bSStefano Zampini } 1317d16cbb6bSStefano Zampini 131888ebb749SStefano Zampini if (n_vertices) { 131906656605SStefano Zampini IS is_aux; 13203a50541eSStefano Zampini 13216816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 13226816873aSStefano Zampini IS tis; 13236816873aSStefano Zampini 13246816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 13256816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 13266816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 13276816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 13286816873aSStefano Zampini } else { 13293a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 13306816873aSStefano Zampini } 13319577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 13329577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 133304708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 13344f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1335019a44ceSStefano Zampini IS dummy; 1336019a44ceSStefano Zampini 13374f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13384f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1339019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1340019a44ceSStefano Zampini } 134125084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 134288ebb749SStefano Zampini } 134388ebb749SStefano Zampini 134488ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1345f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 134606656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 134706656605SStefano Zampini if (pcbddc->coarse_phi_D) { 134806656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 134906656605SStefano Zampini } 1350f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 135106656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 135206656605SStefano Zampini PetscScalar *marray; 135306656605SStefano Zampini 135406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 135506656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1356f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1357f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1358f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1359f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1360f4ddd8eeSStefano Zampini } 1361f4ddd8eeSStefano Zampini } 136206656605SStefano Zampini 1363f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 136406656605SStefano Zampini PetscScalar *marray; 136588ebb749SStefano Zampini 136606656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13678eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 136806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 136988ebb749SStefano Zampini } 13703301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 137106656605SStefano Zampini n *= 2; 137288ebb749SStefano Zampini } 137306656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 137406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 137506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13768eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 137706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 137806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 137988ebb749SStefano Zampini } 13803301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 138106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 13828eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 138306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 138406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 138588ebb749SStefano Zampini } 138688ebb749SStefano Zampini } else { 1387c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1388c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 13891b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1390c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1391c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1392c0553b1fSStefano Zampini } 139388ebb749SStefano Zampini } 139406656605SStefano Zampini } 1395019a44ceSStefano Zampini 139606656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 13974f1b2e48SStefano Zampini p0_lidx_I = NULL; 13984f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1399d12edf2fSStefano Zampini const PetscInt *idxs; 1400d12edf2fSStefano Zampini 1401d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 14024f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 14034f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 14044f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 14054f1b2e48SStefano Zampini } 1406d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1407d12edf2fSStefano Zampini } 1408d16cbb6bSStefano Zampini 140906656605SStefano Zampini /* vertices */ 141006656605SStefano Zampini if (n_vertices) { 141116f15bc4SStefano Zampini 141204708bb6SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 141304708bb6SStefano Zampini 141416f15bc4SStefano Zampini if (n_R) { 141506656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 141606656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 141716f15bc4SStefano Zampini PetscScalar *x,*y; 141804708bb6SStefano Zampini PetscBool isseqaij; 141906656605SStefano Zampini 142021eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 142106656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 142204708bb6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 14236816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 142406656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 142506656605SStefano Zampini } else { 142606656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 142706656605SStefano Zampini for (i=0;i<n_vertices;i++) { 142806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 142906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 143006656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 143106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 143206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 143306656605SStefano Zampini } 143406656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 143506656605SStefano Zampini } 143680677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 143706656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 143806656605SStefano Zampini if (n_constraints) { 143906656605SStefano Zampini Mat B; 144080677318SStefano Zampini 1441b3d85658SStefano Zampini ierr = PetscMemzero(work+n_R*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 144280677318SStefano Zampini for (i=0;i<n_vertices;i++) { 144380677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 144480677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+n_R*n_vertices+i*n_B);CHKERRQ(ierr); 144580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 144680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 144780677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 144880677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 144980677318SStefano Zampini } 145080677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 145180677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 145280677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 145306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 145480677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 145506656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 145606656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 145706656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 145806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 145906656605SStefano Zampini } 146004708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 146104708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 146204708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 146304708bb6SStefano Zampini } 146406656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 146580677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 146606656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 146706656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 146806656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 146906656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 147006656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 147106656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 147206656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1473d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1474019a44ceSStefano Zampini } else { 1475d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1476d16cbb6bSStefano Zampini } 14774f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1478019a44ceSStefano Zampini const PetscScalar *vals; 1479019a44ceSStefano Zampini const PetscInt *idxs; 14804f1b2e48SStefano Zampini PetscInt n,j,primal_idx; 1481019a44ceSStefano Zampini 14824f1b2e48SStefano Zampini ierr = MatGetRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 14834f1b2e48SStefano Zampini primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + i; 1484d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 14854f1b2e48SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+idxs[j]] = vals[j]; 14864f1b2e48SStefano Zampini coarse_submat_vals[idxs[j]*pcbddc->local_primal_size+primal_idx] = vals[j]; 1487019a44ceSStefano Zampini } 14884f1b2e48SStefano Zampini ierr = MatRestoreRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 148916f15bc4SStefano Zampini } 149021eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1491d16cbb6bSStefano Zampini 149206656605SStefano Zampini /* coarse basis functions */ 149306656605SStefano Zampini for (i=0;i<n_vertices;i++) { 149416f15bc4SStefano Zampini PetscScalar *y; 149516f15bc4SStefano Zampini 149606656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 149706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 149806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 149906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 150006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 150106656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 150206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 150306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 150406656605SStefano Zampini 150506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15064f1b2e48SStefano Zampini PetscInt j; 15074f1b2e48SStefano Zampini 150806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 150906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 151006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 151106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 151206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15134f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 151406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 151506656605SStefano Zampini } 151606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 151706656605SStefano Zampini } 151804708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 151904708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 152006656605SStefano Zampini } 152106656605SStefano Zampini 152206656605SStefano Zampini if (n_constraints) { 152306656605SStefano Zampini Mat B; 152406656605SStefano Zampini 152506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 152606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 152780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 152806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 152906656605SStefano Zampini if (n_vertices) { 153080677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 153180677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 153280677318SStefano Zampini } else { 153380677318SStefano Zampini Mat S_VCt; 153480677318SStefano Zampini 153580677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 153680677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 153780677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 153880677318SStefano Zampini } 153906656605SStefano Zampini } 154006656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 154106656605SStefano Zampini /* coarse basis functions */ 154206656605SStefano Zampini for (i=0;i<n_constraints;i++) { 154306656605SStefano Zampini PetscScalar *y; 154406656605SStefano Zampini 154506656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 154606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 154706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 154806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 154906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 155106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 155206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15534f1b2e48SStefano Zampini PetscInt j; 15544f1b2e48SStefano Zampini 155506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 155606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 155706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15604f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 156106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 156206656605SStefano Zampini } 156306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 156406656605SStefano Zampini } 156506656605SStefano Zampini } 156680677318SStefano Zampini if (n_constraints) { 156780677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 156880677318SStefano Zampini } 15694f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 1570019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1571019a44ceSStefano Zampini 157206656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 15733301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 157406656605SStefano Zampini 157506656605SStefano Zampini if (n_constraints) { 157616f15bc4SStefano Zampini Mat S_CCT,B_C; 157706656605SStefano Zampini 157880677318SStefano Zampini /* this is a lazy thing */ 157980677318SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 158006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 158106656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 158206656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 158316f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 158406656605SStefano Zampini if (n_vertices) { 158516f15bc4SStefano Zampini Mat B_V,S_VCT; 158606656605SStefano Zampini 158706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 158806656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 158906656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 159006656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 159116f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 159206656605SStefano Zampini } 159306656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 159480677318SStefano Zampini } else { /* if there are no constraints, reset work */ 159580677318SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 159606656605SStefano Zampini } 159716f15bc4SStefano Zampini if (n_vertices && n_R) { 159806656605SStefano Zampini Mat A_VRT; 159980677318SStefano Zampini PetscScalar *marray; 160006656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 160106656605SStefano Zampini 160280677318SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_VRT);CHKERRQ(ierr); 160380677318SStefano Zampini ierr = MatConvert(A_VRT,impMatType,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 160480677318SStefano Zampini ierr = MatDenseGetArray(A_VRT,&marray);CHKERRQ(ierr); 160506656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 160680677318SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,marray,&B_one,work,&B_one)); 160780677318SStefano Zampini ierr = MatDenseRestoreArray(A_VRT,&marray);CHKERRQ(ierr); 160816f15bc4SStefano Zampini ierr = MatDestroy(&A_VRT);CHKERRQ(ierr); 160906656605SStefano Zampini } 161006656605SStefano Zampini 161106656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 161206656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 161306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 161406656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 161506656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 161606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 161706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 161806656605SStefano Zampini } 161906656605SStefano Zampini } else { 162006656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 162106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 162206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 162306656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 162406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 162506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 162606656605SStefano Zampini } 162706656605SStefano Zampini } 162806656605SStefano Zampini /* coarse basis functions */ 162906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 163006656605SStefano Zampini PetscScalar *y; 163106656605SStefano Zampini 163206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 163306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 163406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 163506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 163606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 163706656605SStefano Zampini if (i<n_vertices) { 163806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 163906656605SStefano Zampini } 164006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 164106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 164206656605SStefano Zampini 164306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 164406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 164506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 164606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 164706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 164806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 164906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 165006656605SStefano Zampini } 165106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 165206656605SStefano Zampini } 165306656605SStefano Zampini } 1654d62866d3SStefano Zampini /* free memory */ 165588ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 165606656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 165706656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 165806656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 165906656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 1660d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1661d62866d3SStefano Zampini if (n_vertices) { 1662d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1663d62866d3SStefano Zampini } 1664d62866d3SStefano Zampini if (n_constraints) { 1665d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 1666d62866d3SStefano Zampini } 166788ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 166888ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 166988ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1670d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 167188ebb749SStefano Zampini Mat coarse_sub_mat; 167225084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 167388ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 167488ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 167588ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 16768bec7fa6SStefano Zampini Mat C_B,CPHI; 16778bec7fa6SStefano Zampini IS is_dummy; 16788bec7fa6SStefano Zampini Vec mones; 167988ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 168088ebb749SStefano Zampini PetscReal real_value; 168188ebb749SStefano Zampini 168288ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 168388ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 168488ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 168588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 168688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 168788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1688c0553b1fSStefano Zampini if (unsymmetric_check) { 168988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 169088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 169188ebb749SStefano Zampini } 169288ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 169388ebb749SStefano Zampini 169425084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 16953301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 169625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1697c0553b1fSStefano Zampini if (unsymmetric_check) { 169888ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 169988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 170088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170188ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 170388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170488ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 170688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170788ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 170988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 171088ebb749SStefano Zampini } else { 171188ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 171288ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 171388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 171488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 171588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 171688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 171788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 171888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 171988ebb749SStefano Zampini } 172088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 172188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 172288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 172388ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 17244f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1725d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 1726d12edf2fSStefano Zampini PetscScalar *data,*data2; 17274f1b2e48SStefano Zampini PetscInt j; 1728d12edf2fSStefano Zampini 17294f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 17304f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 17314f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 1732d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 1733d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 1734d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 1735d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 17364f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 17374f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 1738d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 17394f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 17404f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 17414f1b2e48SStefano Zampini } 1742d12edf2fSStefano Zampini } 1743d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 1744d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 1745d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 1746d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 1747d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 1748d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 1749d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 1750d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1751d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 1752d12edf2fSStefano Zampini } 1753d12edf2fSStefano Zampini #if 0 1754d12edf2fSStefano Zampini { 1755d12edf2fSStefano Zampini PetscViewer viewer; 1756d12edf2fSStefano Zampini char filename[256]; 1757d12edf2fSStefano Zampini sprintf(filename,"proj_local_coarse_mat%d.m",PetscGlobalRank); 1758d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1759d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1760d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 1761d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1762d12edf2fSStefano Zampini } 1763d12edf2fSStefano Zampini #endif 176481d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 17658bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 17660fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 176706656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 17688bec7fa6SStefano Zampini 17698bec7fa6SStefano Zampini /* check constraints */ 17704f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 17718bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 17728bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 17738bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 17748bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 17758bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 17768bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 17778bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1778bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 1779c0553b1fSStefano Zampini if (unsymmetric_check) { 1780bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 1781bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 1782bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 1783bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1784bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 178588ebb749SStefano Zampini } 17868bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 17878bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 17888bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 17898bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 1790d12edf2fSStefano Zampini } 179125084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 179288ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 179388ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 179488ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 179588ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 179688ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 179788ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 179888ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 179988ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 180088ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 180188ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 1802c0553b1fSStefano Zampini if (unsymmetric_check) { 180388ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 180488ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 180588ebb749SStefano Zampini } 180688ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 180788ebb749SStefano Zampini } 18088629588bSStefano Zampini /* get back data */ 18098629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 181088ebb749SStefano Zampini PetscFunctionReturn(0); 181188ebb749SStefano Zampini } 181288ebb749SStefano Zampini 181388ebb749SStefano Zampini #undef __FUNCT__ 1814d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1815d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 1816aa0d41d4SStefano Zampini { 1817d65f70fdSStefano Zampini Mat *work_mat; 1818d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1819d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1820d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1821aa0d41d4SStefano Zampini PetscErrorCode ierr; 1822aa0d41d4SStefano Zampini 1823aa0d41d4SStefano Zampini PetscFunctionBegin; 1824d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1825d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1826d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1827d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1828aa0d41d4SStefano Zampini 1829d65f70fdSStefano Zampini if (!rsorted) { 1830906d46d4SStefano Zampini const PetscInt *idxs; 1831906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 1832aa0d41d4SStefano Zampini 1833d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1834d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1835d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1836d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1837aa0d41d4SStefano Zampini } 1838d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1839d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1840d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1841d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1842aa0d41d4SStefano Zampini } 1843d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1844d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1845d65f70fdSStefano Zampini } else { 1846d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1847d65f70fdSStefano Zampini isrow_s = isrow; 1848aa0d41d4SStefano Zampini } 1849906d46d4SStefano Zampini 1850d65f70fdSStefano Zampini if (!csorted) { 1851d65f70fdSStefano Zampini if (isrow == iscol) { 1852d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1853d65f70fdSStefano Zampini iscol_s = isrow_s; 1854d65f70fdSStefano Zampini } else { 1855d65f70fdSStefano Zampini const PetscInt *idxs; 1856d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1857906d46d4SStefano Zampini 1858d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1859d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1860d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1861d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1862d65f70fdSStefano Zampini } 1863d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1864d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1865d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1866d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1867d65f70fdSStefano Zampini } 1868d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1869d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1870d65f70fdSStefano Zampini } 1871d65f70fdSStefano Zampini } else { 1872d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1873d65f70fdSStefano Zampini iscol_s = iscol; 1874d65f70fdSStefano Zampini } 1875d65f70fdSStefano Zampini 1876d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1877d65f70fdSStefano Zampini 1878d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1879906d46d4SStefano Zampini Mat new_mat; 1880d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1881906d46d4SStefano Zampini 1882d65f70fdSStefano Zampini if (!rsorted) { 1883d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1884d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1885d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1886d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1887906d46d4SStefano Zampini } 1888d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1889d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1890d65f70fdSStefano Zampini } else { 1891d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1892906d46d4SStefano Zampini } 1893d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1894d65f70fdSStefano Zampini 1895d65f70fdSStefano Zampini if (!csorted) { 1896d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1897d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1898d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1899d65f70fdSStefano Zampini } else { 1900d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1901d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1902d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1903d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1904d65f70fdSStefano Zampini } 1905d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1906d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1907d65f70fdSStefano Zampini } 1908d65f70fdSStefano Zampini } else { 1909d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1910d65f70fdSStefano Zampini } 1911d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1912d65f70fdSStefano Zampini 1913d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1914d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1915d65f70fdSStefano Zampini work_mat[0] = new_mat; 1916d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1917d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1918d65f70fdSStefano Zampini } 1919d65f70fdSStefano Zampini 1920d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1921d65f70fdSStefano Zampini *B = work_mat[0]; 1922d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1923d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1924d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1925d65f70fdSStefano Zampini PetscFunctionReturn(0); 1926d65f70fdSStefano Zampini } 1927d65f70fdSStefano Zampini 1928d65f70fdSStefano Zampini #undef __FUNCT__ 19295e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 19305e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1931aa0d41d4SStefano Zampini { 1932aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 19335e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1934d65f70fdSStefano Zampini Mat new_mat; 19355e8657edSStefano Zampini IS is_local,is_global; 1936d65f70fdSStefano Zampini PetscInt local_size; 1937d65f70fdSStefano Zampini PetscBool isseqaij; 1938aa0d41d4SStefano Zampini PetscErrorCode ierr; 1939aa0d41d4SStefano Zampini 1940aa0d41d4SStefano Zampini PetscFunctionBegin; 1941aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 19425e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 19435e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1944b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 1945aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1946d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 1947aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1948906d46d4SStefano Zampini 1949906d46d4SStefano Zampini /* check */ 1950906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1951906d46d4SStefano Zampini Vec x,x_change; 1952906d46d4SStefano Zampini PetscReal error; 1953906d46d4SStefano Zampini 19545e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1955906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 19565e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 1957e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1958e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1959d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 1960e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1961e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1962906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1963906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1964906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1965906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1966906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1967906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1968906d46d4SStefano Zampini } 1969906d46d4SStefano Zampini 197022d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 19719b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 197222d5777bSStefano Zampini if (isseqaij) { 19731cf9b237SStefano Zampini Mat M; 19741cf9b237SStefano Zampini 19751cf9b237SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 19761cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 19771cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1978aa0d41d4SStefano Zampini } else { 19791cf9b237SStefano Zampini Mat work_mat,M; 19801cf9b237SStefano Zampini 1981aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 19821cf9b237SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 19831cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 19841cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1985aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1986aa0d41d4SStefano Zampini } 19873301b35fSStefano Zampini if (matis->A->symmetric_set) { 19883301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 1989e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 19903301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 1991e496cd5dSStefano Zampini #endif 19923301b35fSStefano Zampini } 199345a1bb75SStefano Zampini /* 199445a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1995d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 199645a1bb75SStefano Zampini */ 1997d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1998aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1999aa0d41d4SStefano Zampini } 2000aa0d41d4SStefano Zampini 2001aa0d41d4SStefano Zampini #undef __FUNCT__ 2002a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 20038ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2004a64d13efSStefano Zampini { 2005a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2006a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2007d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 200853892102SStefano Zampini PetscInt *idx_R_local=NULL; 20093a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 20103a50541eSStefano Zampini PetscInt vbs,bs; 20116816873aSStefano Zampini PetscBT bitmask=NULL; 2012a64d13efSStefano Zampini PetscErrorCode ierr; 2013a64d13efSStefano Zampini 2014a64d13efSStefano Zampini PetscFunctionBegin; 2015b23d619eSStefano Zampini /* 2016b23d619eSStefano Zampini No need to setup local scatters if 2017b23d619eSStefano Zampini - primal space is unchanged 2018b23d619eSStefano Zampini AND 2019b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2020b23d619eSStefano Zampini AND 2021b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2022b23d619eSStefano Zampini */ 2023b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2024f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2025f4ddd8eeSStefano Zampini } 2026f4ddd8eeSStefano Zampini /* destroy old objects */ 2027f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2028f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2029f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2030a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2031b371cd4fSStefano Zampini n_B = pcis->n_B; 2032b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2033b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 20343a50541eSStefano Zampini 2035a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 20366816873aSStefano Zampini 203753892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 20386816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 2039854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2040a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2041a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 20420e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2043a64d13efSStefano Zampini } 2044a64d13efSStefano Zampini 2045a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 20464641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 20476816873aSStefano Zampini idx_R_local[n_R++] = i; 2048a64d13efSStefano Zampini } 2049a64d13efSStefano Zampini } 205053892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 20516816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 20526816873aSStefano Zampini 205353892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 205453892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 20556816873aSStefano Zampini } 20563a50541eSStefano Zampini 20573a50541eSStefano Zampini /* Block code */ 20583a50541eSStefano Zampini vbs = 1; 20593a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 20603a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 20613a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 20623a50541eSStefano Zampini PetscInt *vary; 2063d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 2064785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 20653a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2066d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2067d3df7717SStefano 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 */ 20680e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2069d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 20703a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 20713a50541eSStefano Zampini is_blocked = PETSC_FALSE; 20723a50541eSStefano Zampini break; 20733a50541eSStefano Zampini } 20743a50541eSStefano Zampini } 2075d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2076d3df7717SStefano Zampini } else { 2077d3df7717SStefano Zampini /* Verify directly the R set */ 2078d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2079d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2080d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2081d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2082d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2083d3df7717SStefano Zampini break; 2084d3df7717SStefano Zampini } 2085d3df7717SStefano Zampini } 2086d3df7717SStefano Zampini } 2087d3df7717SStefano Zampini } 20883a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 20893a50541eSStefano Zampini vbs = bs; 20903a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 20913a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 20923a50541eSStefano Zampini } 20933a50541eSStefano Zampini } 20943a50541eSStefano Zampini } 20953a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 209653892102SStefano Zampini if (sub_schurs->reuse_mumps) { 209753892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 209853892102SStefano Zampini 209953892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 210053892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 210153892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 210253892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 210353892102SStefano Zampini } else { 21043a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 210553892102SStefano Zampini } 2106a64d13efSStefano Zampini 2107a64d13efSStefano Zampini /* print some info if requested */ 2108a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2109a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2110a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 21110fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2112a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2113a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 21144f1b2e48SStefano 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); 2115a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2116a64d13efSStefano Zampini } 2117a64d13efSStefano Zampini 2118a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 21196816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 21206816873aSStefano Zampini IS is_aux1,is_aux2; 21216816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 21226816873aSStefano Zampini 21233a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2124854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2125854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2126a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 21274641a718SStefano Zampini for (i=0; i<n_D; i++) { 21284641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 21294641a718SStefano Zampini } 2130a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2131a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 21324641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 21334641a718SStefano Zampini aux_array1[j++] = i; 2134a64d13efSStefano Zampini } 2135a64d13efSStefano Zampini } 2136a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2137a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2138a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 21394641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 21404641a718SStefano Zampini aux_array2[j++] = i; 2141a64d13efSStefano Zampini } 2142a64d13efSStefano Zampini } 2143a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2144a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2145a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2146a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2147a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2148a64d13efSStefano Zampini 21498eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2150785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2151a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 21524641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 21534641a718SStefano Zampini aux_array1[j++] = i; 2154a64d13efSStefano Zampini } 2155a64d13efSStefano Zampini } 2156a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2157a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2158a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2159a64d13efSStefano Zampini } 21604641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 21613a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2162d62866d3SStefano Zampini } else { 216353892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 21646816873aSStefano Zampini IS tis; 21656816873aSStefano Zampini PetscInt schur_size; 21666816873aSStefano Zampini 216753892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 21686816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 216953892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 21706816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 21716816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 21726816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 21736816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 21746816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2175d62866d3SStefano Zampini } 2176d62866d3SStefano Zampini } 2177a64d13efSStefano Zampini PetscFunctionReturn(0); 2178a64d13efSStefano Zampini } 2179a64d13efSStefano Zampini 2180304d26faSStefano Zampini 2181304d26faSStefano Zampini #undef __FUNCT__ 2182304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2183684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2184304d26faSStefano Zampini { 2185304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2186304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2187304d26faSStefano Zampini PC pc_temp; 2188304d26faSStefano Zampini Mat A_RR; 2189f4ddd8eeSStefano Zampini MatReuse reuse; 2190304d26faSStefano Zampini PetscScalar m_one = -1.0; 2191304d26faSStefano Zampini PetscReal value; 219204708bb6SStefano Zampini PetscInt n_D,n_R; 21939577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2194304d26faSStefano Zampini PetscErrorCode ierr; 2195e604994aSStefano Zampini /* prefixes stuff */ 2196312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2197e604994aSStefano Zampini size_t len; 2198304d26faSStefano Zampini 2199304d26faSStefano Zampini PetscFunctionBegin; 2200304d26faSStefano Zampini 2201e604994aSStefano Zampini /* compute prefixes */ 2202e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2203e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2204e604994aSStefano Zampini if (!pcbddc->current_level) { 2205e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2206e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2207e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2208e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2209e604994aSStefano Zampini } else { 2210e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2211312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2212e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2213e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2214312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2215312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 221634d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 221734d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2218e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2219e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2220e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2221e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2222e604994aSStefano Zampini } 2223e604994aSStefano Zampini 2224304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2225684f6988SStefano Zampini if (dirichlet) { 2226d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 22273301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 22283301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2229964fefecSStefano Zampini } 2230ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2231964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2232304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2233304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2234304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2235304d26faSStefano Zampini /* default */ 2236304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2237e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 22389577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2239304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 22409577ea80SStefano Zampini if (issbaij) { 22419577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 22429577ea80SStefano Zampini } else { 2243304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 22449577ea80SStefano Zampini } 2245304d26faSStefano Zampini /* Allow user's customization */ 2246304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2247304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2248304d26faSStefano Zampini } 2249d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 2250d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2251d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2252d62866d3SStefano Zampini 2253d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 2254d5574798SStefano Zampini } 2255304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2256304d26faSStefano Zampini if (!n_D) { 2257304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 2258304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2259304d26faSStefano Zampini } 2260304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 2261304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 2262304d26faSStefano Zampini /* set ksp_D into pcis data */ 2263304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 2264304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 2265304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 2266684f6988SStefano Zampini } 2267304d26faSStefano Zampini 2268304d26faSStefano Zampini /* NEUMANN PROBLEM */ 2269684f6988SStefano Zampini A_RR = 0; 2270684f6988SStefano Zampini if (neumann) { 2271d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 227204708bb6SStefano Zampini PetscInt ibs,mbs; 227304708bb6SStefano Zampini PetscBool issbaij; 227404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2275f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 22768ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 2277f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 2278f4ddd8eeSStefano Zampini PetscInt nn_R; 227981d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 2280f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2281f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 2282f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 2283f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 2284f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2285f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2286f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 2287727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 2288f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2289f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2290f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 2291f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 2292f4ddd8eeSStefano Zampini } 2293f4ddd8eeSStefano Zampini } 2294f4ddd8eeSStefano Zampini /* last check */ 2295d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 2296f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2297f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2298f4ddd8eeSStefano Zampini } 2299f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 2300f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2301f4ddd8eeSStefano Zampini } 2302f4ddd8eeSStefano Zampini /* extract A_RR */ 2303af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 2304af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 230504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 230604708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 230704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 230804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 230904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2310af732b37SStefano Zampini } else { 231104708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 23126816873aSStefano Zampini } 231304708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 231404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 231504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 231604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 231704708bb6SStefano Zampini } else { 231804708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 231904708bb6SStefano Zampini } 232004708bb6SStefano Zampini } 232104708bb6SStefano Zampini if (!sub_schurs->reuse_mumps) { 2322f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 23233301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 23243301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 23256816873aSStefano Zampini } 23266816873aSStefano Zampini } else { 23276816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 23286816873aSStefano Zampini 23296816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 23306816873aSStefano Zampini ierr = PCGetOperators(reuse_mumps->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 23316816873aSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2332af732b37SStefano Zampini } 2333f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2334304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2335304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2336304d26faSStefano Zampini /* default */ 2337304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2338e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2339304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 23409577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 23419577ea80SStefano Zampini if (issbaij) { 23429577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 23439577ea80SStefano Zampini } else { 2344304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 23459577ea80SStefano Zampini } 2346304d26faSStefano Zampini /* Allow user's customization */ 2347304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2348304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2349304d26faSStefano Zampini } 2350d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2351304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2352304d26faSStefano Zampini if (!n_R) { 2353304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2354304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2355304d26faSStefano Zampini } 2356d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 2357d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2358d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2359d62866d3SStefano Zampini 2360d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 2361d62866d3SStefano Zampini } 2362304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2363304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2364684f6988SStefano Zampini } 23656816873aSStefano Zampini /* free Neumann problem's matrix */ 23666816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2367304d26faSStefano Zampini 2368304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 23690fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2370684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2371684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2372684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2373684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2374684f6988SStefano Zampini } 2375684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 23760fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 23770fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 23780fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 23790fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 23800fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2381304d26faSStefano Zampini /* need to be adapted? */ 2382b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2383b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2384b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2385304d26faSStefano Zampini /* print info */ 2386304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2387e604994aSStefano 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); 2388304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2389304d26faSStefano Zampini } 2390b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2391298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2392304d26faSStefano Zampini } 2393684f6988SStefano Zampini } 2394684f6988SStefano Zampini if (neumann) { /* Neumann */ 23956816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 23960fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 23970fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 23980fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 23990fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 24000fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2401304d26faSStefano Zampini /* need to be adapted? */ 2402b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2403b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2404304d26faSStefano Zampini /* print info */ 2405304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2406e604994aSStefano 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); 2407304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2408304d26faSStefano Zampini } 2409b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2410298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2411304d26faSStefano Zampini } 24120fccc4e9SStefano Zampini } 2413684f6988SStefano Zampini } 2414304d26faSStefano Zampini PetscFunctionReturn(0); 2415304d26faSStefano Zampini } 2416304d26faSStefano Zampini 2417304d26faSStefano Zampini #undef __FUNCT__ 2418ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 241980677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2420674ae819SStefano Zampini { 2421674ae819SStefano Zampini PetscErrorCode ierr; 2422674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2423be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2424674ae819SStefano Zampini 2425674ae819SStefano Zampini PetscFunctionBegin; 2426be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 242780677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 242820c7b377SStefano Zampini } 242980677318SStefano Zampini if (!pcbddc->switch_static) { 243080677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 243180677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 243280677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 243320c7b377SStefano Zampini } 2434be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 243580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 243680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 243720c7b377SStefano Zampini } else { 2438be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2439be83ff47SStefano Zampini 244053892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 244153892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 244220c7b377SStefano Zampini } 2443be83ff47SStefano Zampini } else { 244480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244880677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 244980677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 245080677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 245180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 245280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2453674ae819SStefano Zampini } 2454674ae819SStefano Zampini } 2455be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 245680677318SStefano Zampini if (applytranspose) { 245780677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 245880677318SStefano Zampini } else { 245980677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 246080677318SStefano Zampini } 246153892102SStefano Zampini #if defined(PETSC_HAVE_MUMPS) 2462be83ff47SStefano Zampini } else { 2463be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2464be83ff47SStefano Zampini 2465be83ff47SStefano Zampini if (applytranspose) { 246653892102SStefano Zampini ierr = MatMumpsSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2467be83ff47SStefano Zampini } else { 246853892102SStefano Zampini ierr = MatMumpsSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2469be83ff47SStefano Zampini } 247053892102SStefano Zampini #endif 2471be83ff47SStefano Zampini } 247280677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 247380677318SStefano Zampini if (!pcbddc->switch_static) { 2474be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 247580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 247680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2477be83ff47SStefano Zampini } else { 2478be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2479be83ff47SStefano Zampini 248053892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 248153892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2482be83ff47SStefano Zampini } 248380677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 248480677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 248580677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 248680677318SStefano Zampini } 248780677318SStefano Zampini } else { 248880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 249380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 249480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 249580677318SStefano Zampini } 249680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2500674ae819SStefano Zampini } 2501674ae819SStefano Zampini PetscFunctionReturn(0); 2502674ae819SStefano Zampini } 2503674ae819SStefano Zampini 2504dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2505674ae819SStefano Zampini #undef __FUNCT__ 2506674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2507dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2508674ae819SStefano Zampini { 2509674ae819SStefano Zampini PetscErrorCode ierr; 2510674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2511674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2512674ae819SStefano Zampini const PetscScalar zero = 0.0; 2513674ae819SStefano Zampini 2514674ae819SStefano Zampini PetscFunctionBegin; 2515dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2516dc359a40SStefano Zampini if (applytranspose) { 2517674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 25188eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2519dc359a40SStefano Zampini } else { 2520674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2521674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 252215aaf578SStefano Zampini } 2523efc2fbd9SStefano Zampini 2524efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 25254f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2526efc2fbd9SStefano Zampini PetscScalar *array; 25274f1b2e48SStefano Zampini PetscInt j; 2528efc2fbd9SStefano Zampini 2529efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 25304f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 2531efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2532efc2fbd9SStefano Zampini } 2533efc2fbd9SStefano Zampini 253412edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 253512edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 253612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253812edc857SStefano Zampini 25399f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 254012edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 254112edc857SStefano Zampini if (pcbddc->coarse_ksp) { 254251694757SStefano Zampini Mat coarse_mat; 2543964fefecSStefano Zampini Vec rhs,sol; 254451694757SStefano Zampini MatNullSpace nullsp; 2545964fefecSStefano Zampini 2546964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2547964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 254851694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 254951694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 255051694757SStefano Zampini if (nullsp) { 255151694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 255251694757SStefano Zampini } 255312edc857SStefano Zampini if (applytranspose) { 2554964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 255512edc857SStefano Zampini } else { 2556964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 255712edc857SStefano Zampini } 255851694757SStefano Zampini if (nullsp) { 255951694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 256051694757SStefano Zampini } 256112edc857SStefano Zampini } 2562674ae819SStefano Zampini 2563674ae819SStefano Zampini /* Local solution on R nodes */ 256480677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 256580677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 25669f00e9b4SStefano Zampini } 2567674ae819SStefano Zampini 25689f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 25699f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 257012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2571674ae819SStefano Zampini 2572674ae819SStefano Zampini /* Sum contributions from two levels */ 2573dc359a40SStefano Zampini if (applytranspose) { 2574dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2575dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2576dc359a40SStefano Zampini } else { 2577674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 25788eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2579dc359a40SStefano Zampini } 2580efc2fbd9SStefano Zampini /* store p0 */ 25814f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2582efc2fbd9SStefano Zampini PetscScalar *array; 25834f1b2e48SStefano Zampini PetscInt j; 2584efc2fbd9SStefano Zampini 2585efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 25864f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 2587efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2588efc2fbd9SStefano Zampini } 2589674ae819SStefano Zampini PetscFunctionReturn(0); 2590674ae819SStefano Zampini } 2591674ae819SStefano Zampini 2592674ae819SStefano Zampini #undef __FUNCT__ 2593674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 259412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2595674ae819SStefano Zampini { 2596674ae819SStefano Zampini PetscErrorCode ierr; 2597674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 259858da7f69SStefano Zampini PetscScalar *array; 259912edc857SStefano Zampini Vec from,to; 2600674ae819SStefano Zampini 2601674ae819SStefano Zampini PetscFunctionBegin; 260212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 260312edc857SStefano Zampini from = pcbddc->coarse_vec; 260412edc857SStefano Zampini to = pcbddc->vec1_P; 260512edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 260612edc857SStefano Zampini Vec tvec; 260758da7f69SStefano Zampini 260858da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 260958da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 261012edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 261158da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 261258da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 261358da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 261412edc857SStefano Zampini } 261512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 261612edc857SStefano Zampini from = pcbddc->vec1_P; 261712edc857SStefano Zampini to = pcbddc->coarse_vec; 261812edc857SStefano Zampini } 261912edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 2620674ae819SStefano Zampini PetscFunctionReturn(0); 2621674ae819SStefano Zampini } 2622674ae819SStefano Zampini 2623674ae819SStefano Zampini #undef __FUNCT__ 2624674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 262512edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 2626674ae819SStefano Zampini { 2627674ae819SStefano Zampini PetscErrorCode ierr; 2628674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 262958da7f69SStefano Zampini PetscScalar *array; 263012edc857SStefano Zampini Vec from,to; 2631674ae819SStefano Zampini 2632674ae819SStefano Zampini PetscFunctionBegin; 263312edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 263412edc857SStefano Zampini from = pcbddc->coarse_vec; 263512edc857SStefano Zampini to = pcbddc->vec1_P; 263612edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 263712edc857SStefano Zampini from = pcbddc->vec1_P; 263812edc857SStefano Zampini to = pcbddc->coarse_vec; 263912edc857SStefano Zampini } 264012edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 264112edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 264212edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 264312edc857SStefano Zampini Vec tvec; 264458da7f69SStefano Zampini 264512edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 264658da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 264758da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 264858da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 264958da7f69SStefano Zampini } 265058da7f69SStefano Zampini } else { 265158da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 265258da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 265312edc857SStefano Zampini } 265412edc857SStefano Zampini } 2655674ae819SStefano Zampini PetscFunctionReturn(0); 2656674ae819SStefano Zampini } 2657674ae819SStefano Zampini 2658984c4197SStefano Zampini /* uncomment for testing purposes */ 2659984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 2660674ae819SStefano Zampini #undef __FUNCT__ 2661674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 2662674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 2663674ae819SStefano Zampini { 2664674ae819SStefano Zampini PetscErrorCode ierr; 2665674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2666674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2667674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2668984c4197SStefano Zampini /* one and zero */ 2669984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 2670984c4197SStefano Zampini /* space to store constraints and their local indices */ 26719162d606SStefano Zampini PetscScalar *constraints_data; 26729162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 26739162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 26749162d606SStefano Zampini PetscInt *constraints_n; 2675984c4197SStefano Zampini /* iterators */ 2676b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 2677984c4197SStefano Zampini /* BLAS integers */ 2678e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2679e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2680c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2681727cdba6SStefano Zampini /* reuse */ 26820e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 26830e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2684984c4197SStefano Zampini /* change of basis */ 2685b3d85658SStefano Zampini PetscBool qr_needed; 26869162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2687984c4197SStefano Zampini /* auxiliary stuff */ 268864efe560SStefano Zampini PetscInt *nnz,*is_indices; 26898a0068c3SStefano Zampini PetscInt ncc; 2690984c4197SStefano Zampini /* some quantities */ 269145a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2692a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2693984c4197SStefano Zampini 2694674ae819SStefano Zampini PetscFunctionBegin; 26958e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 26968e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 26978e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2698088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2699088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 27000e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 27010e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 27020e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 27030e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 27040e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2705088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2706cf5a6209SStefano Zampini 2707cf5a6209SStefano Zampini /* print some info */ 2708cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2709cf5a6209SStefano Zampini IS vertices; 2710cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2711cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2712cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2713cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2714cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2715cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2716cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2717fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2718fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2719cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2720cf5a6209SStefano Zampini } 2721cf5a6209SStefano Zampini 2722cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 27239162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2724cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2725cf5a6209SStefano Zampini const Vec *nearnullvecs; 2726cf5a6209SStefano Zampini Vec *localnearnullsp; 2727cf5a6209SStefano Zampini PetscScalar *array; 2728cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2729cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2730674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2731b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2732674ae819SStefano Zampini PetscScalar *work; 2733674ae819SStefano Zampini PetscReal *singular_vals; 2734674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2735674ae819SStefano Zampini PetscReal *rwork; 2736674ae819SStefano Zampini #endif 2737674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2738674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2739674ae819SStefano Zampini #else 2740964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2741964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2742674ae819SStefano Zampini #endif 2743674ae819SStefano Zampini 2744674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2745d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2746d06fc5fdSStefano Zampini /* free unneeded index sets */ 2747d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2748d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2749674ae819SStefano Zampini } 2750d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2751d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2752d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2753d06fc5fdSStefano Zampini } 2754d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2755d06fc5fdSStefano Zampini n_ISForEdges = 0; 2756d06fc5fdSStefano Zampini } 2757d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2758d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2759d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2760d06fc5fdSStefano Zampini } 2761d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2762d06fc5fdSStefano Zampini n_ISForFaces = 0; 2763d06fc5fdSStefano Zampini } 276470022509SStefano Zampini 276570022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 276670022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 276770022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 276870022509SStefano Zampini if (pcbddc->NullSpace) { 276970022509SStefano Zampini PetscBool tbool[2],gbool[2]; 277070022509SStefano Zampini 277170022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2772b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2773d06fc5fdSStefano Zampini if (!ISForEdges) { 2774d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2775d06fc5fdSStefano Zampini } 2776b8ffe317SStefano Zampini } 2777d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2778d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2779d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2780d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2781d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 278298a51de6SStefano Zampini } 278370022509SStefano Zampini #endif 278408122e43SStefano Zampini 2785674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2786674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2787674ae819SStefano Zampini if (nearnullsp) { 2788674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2789f4ddd8eeSStefano Zampini /* remove any stored info */ 2790f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2791f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2792f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2793f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2794f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2795473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2796f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2797f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2798f4ddd8eeSStefano Zampini } 2799984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2800984c4197SStefano Zampini nnsp_size = 0; 2801674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2802674ae819SStefano Zampini } 2803984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2804984c4197SStefano Zampini max_constraints = nnsp_size; 2805984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2806984c4197SStefano Zampini 2807674ae819SStefano Zampini /* 2808674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 28099162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 28109162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 28119162d606SStefano Zampini There can be multiple constraints per connected component 2812674ae819SStefano Zampini */ 2813674ae819SStefano Zampini n_vertices = 0; 2814674ae819SStefano Zampini if (ISForVertices) { 2815674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2816674ae819SStefano Zampini } 28179162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 28189162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 28199162d606SStefano Zampini 28209162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 28219162d606SStefano Zampini total_counts *= max_constraints; 2822674ae819SStefano Zampini total_counts += n_vertices; 28234641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 28249162d606SStefano Zampini 2825674ae819SStefano Zampini total_counts = 0; 2826674ae819SStefano Zampini max_size_of_constraint = 0; 2827674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 28289162d606SStefano Zampini IS used_is; 2829674ae819SStefano Zampini if (i<n_ISForEdges) { 28309162d606SStefano Zampini used_is = ISForEdges[i]; 2831674ae819SStefano Zampini } else { 28329162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2833674ae819SStefano Zampini } 28349162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2835674ae819SStefano Zampini total_counts += j; 2836674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2837674ae819SStefano Zampini } 28389162d606SStefano 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); 28399162d606SStefano Zampini 2840984c4197SStefano Zampini /* get local part of global near null space vectors */ 2841785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2842984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2843984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2844e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2845e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2846984c4197SStefano Zampini } 2847674ae819SStefano Zampini 2848242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2849242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2850a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2851242a89d7SStefano Zampini 2852984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2853a773dcb8SStefano Zampini if (!skip_lapack) { 2854674ae819SStefano Zampini PetscScalar temp_work; 2855911cabfeSStefano Zampini 2856674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2857984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2858785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2859785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2860785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2861674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2862785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2863674ae819SStefano Zampini #endif 2864674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2865c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2866c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2867674ae819SStefano Zampini lwork = -1; 2868674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2869674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2870c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2871674ae819SStefano Zampini #else 2872c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2873674ae819SStefano Zampini #endif 2874674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2875984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2876674ae819SStefano Zampini #else /* on missing GESVD */ 2877674ae819SStefano Zampini /* SVD */ 2878674ae819SStefano Zampini PetscInt max_n,min_n; 2879674ae819SStefano Zampini max_n = max_size_of_constraint; 2880984c4197SStefano Zampini min_n = max_constraints; 2881984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2882674ae819SStefano Zampini min_n = max_size_of_constraint; 2883984c4197SStefano Zampini max_n = max_constraints; 2884674ae819SStefano Zampini } 2885785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2886674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2887785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2888674ae819SStefano Zampini #endif 2889674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2890674ae819SStefano Zampini lwork = -1; 2891e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2892e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2893b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2894674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2895674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 28969162d606SStefano 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)); 2897674ae819SStefano Zampini #else 28989162d606SStefano 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)); 2899674ae819SStefano Zampini #endif 2900674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2901984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2902984c4197SStefano Zampini #endif /* on missing GESVD */ 2903674ae819SStefano Zampini /* Allocate optimal workspace */ 2904674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2905854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2906674ae819SStefano Zampini } 2907674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2908674ae819SStefano Zampini total_counts = 0; 29099162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 29109162d606SStefano Zampini constraints_data_ptr[0] = 0; 2911674ae819SStefano Zampini /* vertices */ 29129162d606SStefano Zampini if (n_vertices) { 2913674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 29149162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2915674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 29169162d606SStefano Zampini constraints_n[total_counts] = 1; 29179162d606SStefano Zampini constraints_data[total_counts] = 1.0; 29189162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 29199162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2920674ae819SStefano Zampini total_counts++; 2921674ae819SStefano Zampini } 2922674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2923674ae819SStefano Zampini n_vertices = total_counts; 2924674ae819SStefano Zampini } 2925984c4197SStefano Zampini 2926674ae819SStefano Zampini /* edges and faces */ 29279162d606SStefano Zampini total_counts_cc = total_counts; 2928911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 29299162d606SStefano Zampini IS used_is; 29309162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 29319162d606SStefano Zampini 2932911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 29339162d606SStefano Zampini used_is = ISForEdges[ncc]; 2934984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2935674ae819SStefano Zampini } else { 29369162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2937984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2938674ae819SStefano Zampini } 2939674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 29409162d606SStefano Zampini 29419162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 29429162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2943984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2944984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2945674ae819SStefano Zampini if (nnsp_has_cnst) { 29465b08dc53SStefano Zampini PetscScalar quad_value; 29479162d606SStefano Zampini 29489162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 29499162d606SStefano Zampini idxs_copied = PETSC_TRUE; 29509162d606SStefano Zampini 2951a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2952674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2953a773dcb8SStefano Zampini } else { 2954a773dcb8SStefano Zampini quad_value = 1.0; 2955a773dcb8SStefano Zampini } 2956674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 29579162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 2958674ae819SStefano Zampini } 29599162d606SStefano Zampini temp_constraints++; 2960674ae819SStefano Zampini total_counts++; 2961674ae819SStefano Zampini } 2962674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2963984c4197SStefano Zampini PetscReal real_value; 29649162d606SStefano Zampini PetscScalar *ptr_to_data; 29659162d606SStefano Zampini 2966984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 29679162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 2968674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 29699162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 2970674ae819SStefano Zampini } 2971984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2972984c4197SStefano Zampini /* check if array is null on the connected component */ 2973e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 29749162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 29755b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2976674ae819SStefano Zampini temp_constraints++; 2977674ae819SStefano Zampini total_counts++; 29789162d606SStefano Zampini if (!idxs_copied) { 29799162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 29809162d606SStefano Zampini idxs_copied = PETSC_TRUE; 2981674ae819SStefano Zampini } 2982674ae819SStefano Zampini } 29839162d606SStefano Zampini } 29849162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 298545a1bb75SStefano Zampini valid_constraints = temp_constraints; 2986eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2987a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 29889162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 29899162d606SStefano Zampini 29909162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2991a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 29929162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 2993a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 29949162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 2995a773dcb8SStefano Zampini } else { /* perform SVD */ 2996984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 29979162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2998674ae819SStefano Zampini 2999674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3000984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3001984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3002984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3003984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3004984c4197SStefano Zampini from that computed using LAPACKgesvd 3005984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3006984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3007984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3008674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3009e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3010984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3011674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3012674ae819SStefano Zampini for (k=0;k<j+1;k++) { 30139162d606SStefano 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)); 3014674ae819SStefano Zampini } 3015674ae819SStefano Zampini } 3016e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3017e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3018e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3019674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3020c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3021674ae819SStefano Zampini #else 3022c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3023674ae819SStefano Zampini #endif 3024674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3025984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3026984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3027674ae819SStefano Zampini j = 0; 3028984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3029674ae819SStefano Zampini total_counts = total_counts-j; 303045a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3031e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3032c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3033c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3034c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3035c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3036c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3037c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3038674ae819SStefano Zampini if (j<temp_constraints) { 3039984c4197SStefano Zampini PetscInt ii; 3040984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3041674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30429162d606SStefano 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)); 3043674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3044984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3045674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 30469162d606SStefano 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]; 3047674ae819SStefano Zampini } 3048674ae819SStefano Zampini } 3049674ae819SStefano Zampini } 3050674ae819SStefano Zampini #else /* on missing GESVD */ 3051e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3052e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3053b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3054674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3055674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 30569162d606SStefano 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)); 3057674ae819SStefano Zampini #else 30589162d606SStefano 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)); 3059674ae819SStefano Zampini #endif 3060984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3061674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3062984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3063e310c8b4SStefano Zampini k = temp_constraints; 3064e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3065674ae819SStefano Zampini j = 0; 3066e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 306745a1bb75SStefano Zampini valid_constraints = k-j; 3068911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3069984c4197SStefano Zampini #endif /* on missing GESVD */ 3070674ae819SStefano Zampini } 3071a773dcb8SStefano Zampini } 30729162d606SStefano Zampini /* update pointers information */ 30739162d606SStefano Zampini if (valid_constraints) { 30749162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 30759162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 30769162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 30779162d606SStefano Zampini /* set change_of_basis flag */ 307845a1bb75SStefano Zampini if (boolforchange) { 3079b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 30809162d606SStefano Zampini } 3081b3d85658SStefano Zampini total_counts_cc++; 308245a1bb75SStefano Zampini } 308345a1bb75SStefano Zampini } 3084984c4197SStefano Zampini /* free workspace */ 30858f1c130eSStefano Zampini if (!skip_lapack) { 3086984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3087984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3088984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3089984c4197SStefano Zampini #endif 3090984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3091984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3092984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3093984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3094984c4197SStefano Zampini #endif 3095984c4197SStefano Zampini } 3096984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3097984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3098984c4197SStefano Zampini } 3099984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3100cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3101cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3102cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3103cf5a6209SStefano Zampini } 3104cf5a6209SStefano Zampini if (n_ISForFaces) { 3105cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3106cf5a6209SStefano Zampini } 3107cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3108cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3109cf5a6209SStefano Zampini } 3110cf5a6209SStefano Zampini if (n_ISForEdges) { 3111cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3112cf5a6209SStefano Zampini } 3113cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 311408122e43SStefano Zampini } else { 311508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3116984c4197SStefano Zampini 311708122e43SStefano Zampini total_counts = 0; 311808122e43SStefano Zampini n_vertices = 0; 3119d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3120d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 312108122e43SStefano Zampini } 312208122e43SStefano Zampini max_constraints = 0; 31239162d606SStefano Zampini total_counts_cc = 0; 312408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 312508122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 31269162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 312708122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 312808122e43SStefano Zampini } 31299162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 31309162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 31319162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 31329162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 313374d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 31349162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 31359162d606SStefano Zampini total_counts_cc = 0; 31369162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 31379162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 31389162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 313908122e43SStefano Zampini } 314008122e43SStefano Zampini } 31419162d606SStefano Zampini #if 0 31429162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 31439162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 31449162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 31459162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 31469162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 31479162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 31489162d606SStefano Zampini } 31499162d606SStefano Zampini printf("\n"); 31509162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 31519162d606SStefano Zampini } 31521b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 31538bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 31541b968477SStefano Zampini } 31551b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 31568bec7fa6SStefano 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]); 31571b968477SStefano Zampini } 315808122e43SStefano Zampini #endif 315908122e43SStefano Zampini 31608bec7fa6SStefano Zampini max_size_of_constraint = 0; 31619162d606SStefano 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]); 31629162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 316308122e43SStefano Zampini /* Change of basis */ 3164b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 316508122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 316608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 316708122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3168b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 316908122e43SStefano Zampini } 317008122e43SStefano Zampini } 317108122e43SStefano Zampini } 317208122e43SStefano Zampini } 3173984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 31744f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 317508122e43SStefano Zampini 31769162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 31779162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 31789162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 31799162d606SStefano 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); 318008122e43SStefano Zampini } 3181674ae819SStefano Zampini 3182674ae819SStefano Zampini /* Create constraint matrix */ 3183674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 318416f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3185984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3186984c4197SStefano Zampini 3187984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3188a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3189a717540cSStefano Zampini qr_needed = PETSC_FALSE; 319074d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3191984c4197SStefano Zampini total_primal_vertices=0; 3192b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 31939162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 31949162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3195984c4197SStefano Zampini if (size_of_constraint == 1) { 31969162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 3197b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 319864efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 31999162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 32009162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 3201a717540cSStefano Zampini } 3202b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 320374d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 3204a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 3205a717540cSStefano Zampini qr_needed = PETSC_TRUE; 3206a717540cSStefano Zampini } 3207fa434743SStefano Zampini } else { 3208b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 3209fa434743SStefano Zampini } 3210a717540cSStefano Zampini } 3211b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 3212b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 3213674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 321470022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3215b3d85658SStefano Zampini 32164f1b2e48SStefano 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); 32170e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 32180e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 3219984c4197SStefano Zampini 3220984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 322174d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 3222785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 3223984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 322474d5cdf7SStefano Zampini 3225984c4197SStefano Zampini j = total_primal_vertices; 322674d5cdf7SStefano Zampini total_counts = total_primal_vertices; 3227b3d85658SStefano Zampini cum = total_primal_vertices; 32289162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32294641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 3230b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 3231b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 3232b3d85658SStefano Zampini cum++; 32339162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 323474d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 323574d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 323674d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 323774d5cdf7SStefano Zampini } 32389162d606SStefano Zampini j += constraints_n[i]; 3239674ae819SStefano Zampini } 3240674ae819SStefano Zampini } 3241674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 3242674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3243088faed8SStefano Zampini 3244674ae819SStefano Zampini /* set values in constraint matrix */ 3245984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 32460e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3247674ae819SStefano Zampini } 3248984c4197SStefano Zampini total_counts = total_primal_vertices; 32499162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32504641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 32519162d606SStefano Zampini PetscInt *cols; 32529162d606SStefano Zampini 32539162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 32549162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 32559162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 32569162d606SStefano Zampini PetscInt row = total_counts+k; 32579162d606SStefano Zampini PetscScalar *vals; 32589162d606SStefano Zampini 32599162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 32609162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 32619162d606SStefano Zampini } 32629162d606SStefano Zampini total_counts += constraints_n[i]; 3263674ae819SStefano Zampini } 3264674ae819SStefano Zampini } 3265674ae819SStefano Zampini /* assembling */ 3266674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3267674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3268088faed8SStefano Zampini 3269984c4197SStefano Zampini /* 327045a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3271984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 3272984c4197SStefano Zampini */ 3273674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 3274674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 3275026de310SStefano Zampini /* dual and primal dofs on a single cc */ 3276984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 3277984c4197SStefano Zampini /* working stuff for GEQRF */ 327881d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 3279984c4197SStefano Zampini PetscBLASInt lqr_work; 3280984c4197SStefano Zampini /* working stuff for UNGQR */ 3281984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 3282984c4197SStefano Zampini PetscBLASInt lgqr_work; 3283984c4197SStefano Zampini /* working stuff for TRTRS */ 3284984c4197SStefano Zampini PetscScalar *trs_rhs; 32853f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 3286984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 3287984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 3288984c4197SStefano Zampini PetscScalar *start_vals; 3289984c4197SStefano Zampini /* working stuff for values insertion */ 32904641a718SStefano Zampini PetscBT is_primal; 329164efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 3292906d46d4SStefano Zampini /* matrix sizes */ 3293906d46d4SStefano Zampini PetscInt global_size,local_size; 3294906d46d4SStefano Zampini /* temporary change of basis */ 3295906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 3296cf5a6209SStefano Zampini /* extra space for debugging */ 3297cf5a6209SStefano Zampini PetscScalar *dbg_work; 3298984c4197SStefano Zampini 3299906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 3300906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 330116f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 3302bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3303906d46d4SStefano Zampini /* nonzeros for local mat */ 3304bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 3305bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 33069162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 3307a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 33089162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3309a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 33109162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3311a717540cSStefano Zampini } else { 33129162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 33139162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3314a717540cSStefano Zampini } 3315a717540cSStefano Zampini } 3316a717540cSStefano Zampini } 3317906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3318bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3319a717540cSStefano Zampini /* Set initial identity in the matrix */ 3320bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3321906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3322a717540cSStefano Zampini } 3323a717540cSStefano Zampini 3324a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3325a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3326a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3327a717540cSStefano Zampini } 3328a717540cSStefano Zampini 3329a717540cSStefano Zampini 3330a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3331a717540cSStefano Zampini /* 3332a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3333a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3334a717540cSStefano Zampini 3335a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3336a717540cSStefano Zampini 3337a6b551f4SStefano 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) 3338a6b551f4SStefano Zampini 3339a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3340a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3341a717540cSStefano Zampini | ... | 3342a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3343a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3344a717540cSStefano Zampini 3345a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3346a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3347a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3348a6b551f4SStefano Zampini 3349a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3350a717540cSStefano Zampini */ 3351a717540cSStefano Zampini if (qr_needed) { 3352984c4197SStefano Zampini /* space to store Q */ 3353854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3354984c4197SStefano Zampini /* first we issue queries for optimal work */ 33553f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 33563f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 33573f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3358984c4197SStefano Zampini lqr_work = -1; 33593f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3360984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3361984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3362785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3363984c4197SStefano Zampini lgqr_work = -1; 33643f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 33653f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 33663f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 33673f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 33683f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 33693f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3370984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3371984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3372785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3373984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3374785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3375984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3376785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3377a717540cSStefano Zampini /* allocating workspace for check */ 3378a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3379cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3380a717540cSStefano Zampini } 3381a717540cSStefano Zampini } 3382984c4197SStefano Zampini /* array to store whether a node is primal or not */ 33834641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3384473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 33850e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 338639e2fb2aSStefano Zampini if (i != total_primal_vertices) { 338739e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 33884641a718SStefano Zampini } 338939e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 339039e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 339139e2fb2aSStefano Zampini } 339239e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3393984c4197SStefano Zampini 3394a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 33959162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 33969162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 33974641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3398984c4197SStefano Zampini /* get constraint info */ 33999162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3400984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3401984c4197SStefano Zampini 3402984c4197SStefano Zampini if (pcbddc->dbg_flag) { 34039162d606SStefano 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); 3404674ae819SStefano Zampini } 3405984c4197SStefano Zampini 3406fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3407a717540cSStefano Zampini 3408a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3409a717540cSStefano Zampini if (pcbddc->dbg_flag) { 34109162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3411a717540cSStefano Zampini } 3412984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 34139162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3414984c4197SStefano Zampini 3415984c4197SStefano Zampini /* compute QR decomposition of constraints */ 34163f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34173f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3419674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34203f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3421984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3422674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3423984c4197SStefano Zampini 3424984c4197SStefano Zampini /* explictly compute R^-T */ 3425984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3426984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 34273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34283f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 34293f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34303f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3431984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34323f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3433984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3434984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3435984c4197SStefano Zampini 3436a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 34373f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34383f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34393f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34403f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3441984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34423f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3443984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3444984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3445984c4197SStefano Zampini 3446984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3447984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3448984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 34493f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34503f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34513f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34523f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34533f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 34543f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3455984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34569162d606SStefano 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)); 3457984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 34589162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3459984c4197SStefano Zampini 3460984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 34619162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3462984c4197SStefano Zampini /* insert cols for primal dofs */ 3463984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3464984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 34659162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3466906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3467984c4197SStefano Zampini } 3468984c4197SStefano Zampini /* insert cols for dual dofs */ 3469984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 34709162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3471984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 34729162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3473906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3474984c4197SStefano Zampini j++; 3475674ae819SStefano Zampini } 3476674ae819SStefano Zampini } 3477984c4197SStefano Zampini 3478984c4197SStefano Zampini /* check change of basis */ 3479984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3480984c4197SStefano Zampini PetscInt ii,jj; 3481984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3482c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3483c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3484c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3485c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3486c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3487c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3488984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3489cf5a6209SStefano 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)); 3490984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3491984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3492984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3493cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3494cf5a6209SStefano 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; 3495674ae819SStefano Zampini } 3496674ae819SStefano Zampini } 3497984c4197SStefano Zampini if (!valid_qr) { 349822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3499984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3500984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3501cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3502cf5a6209SStefano 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])); 3503674ae819SStefano Zampini } 3504cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3505cf5a6209SStefano 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])); 3506984c4197SStefano Zampini } 3507984c4197SStefano Zampini } 3508984c4197SStefano Zampini } 3509674ae819SStefano Zampini } else { 351022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3511674ae819SStefano Zampini } 3512674ae819SStefano Zampini } 3513a717540cSStefano Zampini } else { /* simple transformation block */ 3514a717540cSStefano Zampini PetscInt row,col; 3515a6b551f4SStefano Zampini PetscScalar val,norm; 3516a6b551f4SStefano Zampini 3517a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 35189162d606SStefano 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)); 3519a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 35209162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 35219162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3522bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 35239162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3524906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 35259162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3526a717540cSStefano Zampini } else { 3527a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 35289162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3529a717540cSStefano Zampini if (row != col) { 35309162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3531a717540cSStefano Zampini } else { 35329162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3533a717540cSStefano Zampini } 3534906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3535a717540cSStefano Zampini } 3536a717540cSStefano Zampini } 3537a717540cSStefano Zampini } 353898a51de6SStefano Zampini if (pcbddc->dbg_flag) { 353922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3540a717540cSStefano Zampini } 3541674ae819SStefano Zampini } 3542984c4197SStefano Zampini } else { 3543984c4197SStefano Zampini if (pcbddc->dbg_flag) { 35449162d606SStefano 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); 3545674ae819SStefano Zampini } 3546674ae819SStefano Zampini } 3547674ae819SStefano Zampini } 3548a717540cSStefano Zampini 3549a717540cSStefano Zampini /* free workspace */ 3550a717540cSStefano Zampini if (qr_needed) { 3551984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3552cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3553984c4197SStefano Zampini } 3554984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3555984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3556984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3557984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3558984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3559674ae819SStefano Zampini } 3560a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3561906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3562906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3563906d46d4SStefano Zampini 3564906d46d4SStefano Zampini /* assembling of global change of variable */ 3565bbb9e6c6SStefano Zampini { 3566bbb9e6c6SStefano Zampini Mat tmat; 356716f15bc4SStefano Zampini PetscInt bs; 356816f15bc4SStefano Zampini 3569906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3570906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3571bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3572bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3573bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3574bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 357516f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 357616f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3577906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3578bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3579bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3580bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3581bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3582bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3583e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3584e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3585bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3586bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3587906d46d4SStefano Zampini } 3588906d46d4SStefano Zampini /* check */ 3589906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3590906d46d4SStefano Zampini PetscReal error; 3591906d46d4SStefano Zampini Vec x,x_change; 3592906d46d4SStefano Zampini 3593906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3594906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3595906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3596906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3597e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3598e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3599bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 3600e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3601e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3602906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 3603906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3604906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3605906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3606bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 3607906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3608906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3609906d46d4SStefano Zampini } 3610b96c3477SStefano Zampini 3611b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 3612b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3613b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 3614b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 3615ac632422SStefano Zampini Mat S_new,tmat; 3616b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 3617b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 3618b087196eSStefano Zampini const PetscScalar *array; 3619b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 3620b087196eSStefano Zampini PetscInt i,n_V; 3621bbb9e6c6SStefano Zampini 3622bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 36236816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 3624b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 3625b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 3626b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 3627b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 3628bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 3629b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 3630ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3631b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 3632ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3633b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3634b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 3635b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3636b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3637b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 3638b087196eSStefano Zampini for (i=0;i<n_V;i++) { 3639b087196eSStefano Zampini PetscScalar val; 3640b087196eSStefano Zampini PetscInt idx; 3641b087196eSStefano Zampini 3642b087196eSStefano Zampini idx = idxs_V[i]; 3643b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 3644b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 3645b087196eSStefano Zampini } 3646b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3647b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3648ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 3649ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3650ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 3651ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3652b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 3653ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3654b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3655ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 3656ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3657ac632422SStefano Zampini } 3658b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 3659b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3660b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3661b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3662b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 3663b96c3477SStefano Zampini } 3664b96c3477SStefano Zampini } 3665906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 3666906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 3667b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3668b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 3669b9b85e73SStefano Zampini } 3670906d46d4SStefano Zampini 3671906d46d4SStefano Zampini /* set up change of basis context */ 3672906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 3673906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 3674906d46d4SStefano Zampini 3675906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 3676906d46d4SStefano Zampini PetscInt global_size,local_size; 3677906d46d4SStefano Zampini 3678906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3679906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3680906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 3681906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3682906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 3683906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 3684906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3685906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3686906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3687906d46d4SStefano Zampini } else { 3688906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3689906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3690906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3691906d46d4SStefano Zampini } 3692906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3693906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3694906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3695906d46d4SStefano Zampini } else { 3696906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3697906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3698906d46d4SStefano Zampini } 3699906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3700906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3701906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3702906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3703b9b85e73SStefano Zampini } 3704a717540cSStefano Zampini 37054f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 37064f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 37074f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 37084f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 3709019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 3710019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 3711019a44ceSStefano Zampini pcbddc->local_primal_size++; 3712019a44ceSStefano Zampini } 3713019a44ceSStefano Zampini 3714019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 3715727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3716727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 37179f47a83aSStefano 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); 3718c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 37190e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 37209f47a83aSStefano 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); 3721727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3722727cdba6SStefano Zampini } 37230e6343abSStefano Zampini } 37240e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3725727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3726727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3727727cdba6SStefano Zampini 3728a717540cSStefano Zampini /* flush dbg viewer */ 3729b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3730b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3731b8ffe317SStefano Zampini } 3732a717540cSStefano Zampini 3733e310c8b4SStefano Zampini /* free workspace */ 3734a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 37354641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 373608122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 37379162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 37389162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 373908122e43SStefano Zampini } else { 37409162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 37419162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 37429162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 374308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 374408122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 37459162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 37469162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 374708122e43SStefano Zampini } 3748674ae819SStefano Zampini PetscFunctionReturn(0); 3749674ae819SStefano Zampini } 3750674ae819SStefano Zampini 3751674ae819SStefano Zampini #undef __FUNCT__ 3752674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3753674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3754674ae819SStefano Zampini { 3755674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3756674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3757674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 37587fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3759674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3760674ae819SStefano Zampini 3761674ae819SStefano Zampini PetscFunctionBegin; 37628e61c736SStefano Zampini /* Reset previously computed graph */ 37638e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3764674ae819SStefano Zampini /* Init local Graph struct */ 37657fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 37663bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3767674ae819SStefano Zampini 3768575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 37695099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 37705099eff2SStefano 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); 3771575ad6abSStefano Zampini } 37729577ea80SStefano Zampini 3773674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 37744d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 37754d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 37764d379d7bSStefano Zampini PetscInt nvtxs; 3777e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3778674ae819SStefano Zampini 37794d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 37802fffb893SStefano Zampini 37812fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 37822fffb893SStefano Zampini if (flg_row) { 37834d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3784b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 37852fffb893SStefano Zampini } 37862fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 37879b28b941SStefano 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 */ 37884d379d7bSStefano Zampini IS is_dummy; 37894d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 37904d379d7bSStefano Zampini PetscInt j,sum; 37914d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 37924d379d7bSStefano Zampini const PetscInt *idxs; 37934d379d7bSStefano Zampini PCBDDCGraph graph; 37944d379d7bSStefano Zampini PetscBT is_on_boundary; 37954d379d7bSStefano Zampini 37964d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 37974d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 37984d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 37994d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 38007fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 38014d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3802e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3803e496cd5dSStefano Zampini if (flg_row) { 38044d379d7bSStefano Zampini graph->xadj = xadj; 38054d379d7bSStefano Zampini graph->adjncy = adjncy; 3806e496cd5dSStefano Zampini } 38074d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 38084d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3809e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 38104d379d7bSStefano Zampini 38114d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 38129b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 38134d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38144d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 38154d379d7bSStefano Zampini } 38164d379d7bSStefano Zampini } 38174d379d7bSStefano Zampini 3818e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 38194d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38204d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 38214d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 38224d379d7bSStefano Zampini } 38234d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38244d379d7bSStefano Zampini 3825e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 38264d379d7bSStefano Zampini sum = 0; 38274d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38284d379d7bSStefano Zampini PetscInt sizecc = 0; 38294d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38304d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38314d379d7bSStefano Zampini sizecc++; 38324d379d7bSStefano Zampini } 38334d379d7bSStefano Zampini } 38344d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38354d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38364d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 38374d379d7bSStefano Zampini } 38384d379d7bSStefano Zampini } 38394d379d7bSStefano Zampini sum += sizecc*sizecc; 38404d379d7bSStefano Zampini } 38414d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 38424d379d7bSStefano Zampini sum = 0; 3843e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 38444d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 38454d379d7bSStefano Zampini cxadj[i] = sum; 38464d379d7bSStefano Zampini sum += temp; 38474d379d7bSStefano Zampini } 3848e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 38494d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38504d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38514d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38524d379d7bSStefano Zampini PetscInt k,sizecc = 0; 38534d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 38544d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 38554d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 38564d379d7bSStefano Zampini sizecc++; 38574d379d7bSStefano Zampini } 38584d379d7bSStefano Zampini } 38594d379d7bSStefano Zampini } 38604d379d7bSStefano Zampini } 38614d379d7bSStefano Zampini } 38629b28b941SStefano Zampini if (sum) { 3863e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 38644d379d7bSStefano Zampini } else { 38654d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 38664d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 38674d379d7bSStefano Zampini } 38684d379d7bSStefano Zampini graph->xadj = 0; 38694d379d7bSStefano Zampini graph->adjncy = 0; 38704d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 38714d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 38724d379d7bSStefano Zampini } 3873674ae819SStefano Zampini } 38749b28b941SStefano Zampini if (pcbddc->dbg_flag) { 38759b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3876674ae819SStefano Zampini } 3877674ae819SStefano Zampini 387863602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3879674ae819SStefano Zampini vertex_size = 1; 388063602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 388163602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 388295ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 388363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3884e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 388563602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3886674ae819SStefano Zampini } 388763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 388863602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 388963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3890674ae819SStefano Zampini } 389163602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3892674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 389363602bcaSStefano Zampini } else { 389463602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 389563602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3896854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 389763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 389863602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 389963602bcaSStefano Zampini } 390063602bcaSStefano Zampini } 3901674ae819SStefano Zampini } 3902674ae819SStefano Zampini 3903674ae819SStefano Zampini /* Setup of Graph */ 3904785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3905e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3906785d1243SStefano Zampini } 3907785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3908e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3909785d1243SStefano Zampini } 3910*30368db7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { /* need to convert from global to local */ 3911*30368db7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3912*30368db7SStefano Zampini } 3913*30368db7SStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3914674ae819SStefano Zampini 39154f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 39164f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 39174f1b2e48SStefano Zampini PetscInt *local_subs; 39184f1b2e48SStefano Zampini 39194f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 39204f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 39214f1b2e48SStefano Zampini const PetscInt *idxs; 39224f1b2e48SStefano Zampini PetscInt nl,j; 39234f1b2e48SStefano Zampini 39244f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 39254f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39264f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 39274f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 39284f1b2e48SStefano Zampini } 39294f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39304f1b2e48SStefano Zampini } 39314f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 39324f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 39334f1b2e48SStefano Zampini } 39344f1b2e48SStefano Zampini 3935674ae819SStefano Zampini /* Graph's connected components analysis */ 3936674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3937674ae819SStefano Zampini 3938674ae819SStefano Zampini /* print some info to stdout */ 3939674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3940302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3941674ae819SStefano Zampini } 3942fb180af4SStefano Zampini 3943fb180af4SStefano Zampini /* mark topography has done */ 3944fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3945674ae819SStefano Zampini PetscFunctionReturn(0); 3946674ae819SStefano Zampini } 3947674ae819SStefano Zampini 3948dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3949674ae819SStefano Zampini #undef __FUNCT__ 3950674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3951dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3952674ae819SStefano Zampini { 3953dc456d91SStefano Zampini PetscSF sf; 3954dc456d91SStefano Zampini PetscLayout map; 3955dc456d91SStefano Zampini const PetscInt *idxs; 3956dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 3957dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 3958dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 3959dc456d91SStefano Zampini PetscMPIInt commsize; 3960674ae819SStefano Zampini PetscBool first_found; 3961674ae819SStefano Zampini PetscErrorCode ierr; 3962674ae819SStefano Zampini 3963674ae819SStefano Zampini PetscFunctionBegin; 3964dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 3965dc456d91SStefano Zampini if (subset_mult) { 3966dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 3967dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 3968dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 3969674ae819SStefano Zampini } 3970dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 3971dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 3972dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 3973dc456d91SStefano Zampini for (i=0;i<n;i++) { 3974dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 3975dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 3976674ae819SStefano Zampini } 3977dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 3978dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3979dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 3980dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 3981dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 3982dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 3983dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 3984dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 3985dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 3986dc456d91SStefano Zampini 3987dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 3988dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 3989dc456d91SStefano Zampini if (subset_mult) { 3990dc456d91SStefano Zampini const PetscInt* idxs_mult; 3991dc456d91SStefano Zampini 3992dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3993dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 3994dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3995674ae819SStefano Zampini } else { 3996dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 3997674ae819SStefano Zampini } 3998dc456d91SStefano Zampini /* local size of new subset */ 3999dc456d91SStefano Zampini n_n = 0; 4000dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4001dc456d91SStefano Zampini 4002dc456d91SStefano Zampini /* global indexes in layout */ 4003dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4004dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4005dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4006dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4007dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4008dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4009dc456d91SStefano Zampini 4010dc456d91SStefano Zampini /* reduce from leaves to roots */ 4011dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 401264a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 401364a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4014dc456d91SStefano Zampini 4015dc456d91SStefano Zampini /* count indexes in local part of layout */ 4016674ae819SStefano Zampini nlocals = 0; 4017674ae819SStefano Zampini first_index = -1; 4018674ae819SStefano Zampini first_found = PETSC_FALSE; 4019dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4020dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4021674ae819SStefano Zampini first_found = PETSC_TRUE; 4022674ae819SStefano Zampini first_index = i; 4023674ae819SStefano Zampini } 4024dc456d91SStefano Zampini nlocals += root_data[i]; 4025674ae819SStefano Zampini } 4026dc456d91SStefano Zampini 4027dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 40285fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4029dc456d91SStefano Zampini start = 0; 403064a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40315fa240b1SStefano Zampini #else 403264a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40335fa240b1SStefano Zampini start = start-nlocals; 40345fa240b1SStefano Zampini #endif 40355fa240b1SStefano Zampini 4036dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4037dc456d91SStefano Zampini *N_n = start + nlocals; 4038dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4039dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4040674ae819SStefano Zampini } 40415fa240b1SStefano Zampini 40425fa240b1SStefano Zampini /* adapt root data with cumulative */ 4043674ae819SStefano Zampini if (first_found) { 4044dc456d91SStefano Zampini PetscInt old_index; 4045dc456d91SStefano Zampini 4046dc456d91SStefano Zampini root_data[first_index] += start; 4047674ae819SStefano Zampini old_index = first_index; 4048dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4049dc456d91SStefano Zampini if (root_data[i]) { 4050dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4051674ae819SStefano Zampini old_index = i; 4052674ae819SStefano Zampini } 4053674ae819SStefano Zampini } 4054674ae819SStefano Zampini } 4055dc456d91SStefano Zampini 4056dc456d91SStefano Zampini /* from roots to leaves */ 4057dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4058dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4059dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4060dc456d91SStefano Zampini 4061dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4062dc456d91SStefano Zampini if (subset_mult) { 4063dc456d91SStefano Zampini const PetscInt* idxs_mult; 4064dc456d91SStefano Zampini PetscInt cum; 4065dc456d91SStefano Zampini 4066dc456d91SStefano Zampini cum = 0; 4067dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4068dc456d91SStefano Zampini for (i=0;i<n;i++) { 4069dc456d91SStefano Zampini PetscInt j; 4070dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4071674ae819SStefano Zampini } 4072dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4073674ae819SStefano Zampini } else { 4074dc456d91SStefano Zampini for (i=0;i<n;i++) { 4075dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4076674ae819SStefano Zampini } 4077674ae819SStefano Zampini } 4078dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4079dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4080674ae819SStefano Zampini PetscFunctionReturn(0); 4081674ae819SStefano Zampini } 40829a7d3425SStefano Zampini 40839a7d3425SStefano Zampini #undef __FUNCT__ 40849a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 40859a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 40869a7d3425SStefano Zampini { 40879a7d3425SStefano Zampini PetscInt i,j; 40889a7d3425SStefano Zampini PetscScalar *alphas; 40899a7d3425SStefano Zampini PetscErrorCode ierr; 40909a7d3425SStefano Zampini 40919a7d3425SStefano Zampini PetscFunctionBegin; 40929a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4093785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 40949a7d3425SStefano Zampini for (i=0;i<n;i++) { 40959a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 40969a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 40979a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 40989a7d3425SStefano Zampini } 40999a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 41009a7d3425SStefano Zampini PetscFunctionReturn(0); 41019a7d3425SStefano Zampini } 41029a7d3425SStefano Zampini 4103e7931f94SStefano Zampini #undef __FUNCT__ 410470cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 4105b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 4106e7931f94SStefano Zampini { 410752e5ac9dSStefano Zampini IS ranks_send_to; 4108e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4109e7931f94SStefano Zampini PetscMPIInt size,rank,color; 411052e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 411152e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 41123837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 41132b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 4114e7931f94SStefano Zampini PetscSubcomm subcomm; 411552e5ac9dSStefano Zampini PetscErrorCode ierr; 4116a57a6d2fSStefano Zampini 4117e7931f94SStefano Zampini PetscFunctionBegin; 41182b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 41192b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 41202b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 4121e7931f94SStefano Zampini 4122e7931f94SStefano Zampini /* Get info on mapping */ 41233bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 41243bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4125e7931f94SStefano Zampini 4126e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4127785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4128e7931f94SStefano Zampini xadj[0] = 0; 4129e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4130785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4131785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 4132e7931f94SStefano Zampini 41332b510759SStefano Zampini if (threshold) { 4134d023bfaeSStefano Zampini PetscInt xadj_count = 0; 41352b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 4136d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 4137d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4138d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4139d023bfaeSStefano Zampini xadj_count++; 4140e7931f94SStefano Zampini } 4141e7931f94SStefano Zampini } 4142d023bfaeSStefano Zampini xadj[1] = xadj_count; 4143c8587f34SStefano Zampini } else { 4144e7931f94SStefano Zampini if (xadj[1]) { 4145e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 4146e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 4147c8587f34SStefano Zampini } 4148e7931f94SStefano Zampini } 41493bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4150e7931f94SStefano Zampini if (use_square) { 4151e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4152e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 4153e7931f94SStefano Zampini } 4154e7931f94SStefano Zampini } 4155e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4156e7931f94SStefano Zampini 41573837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4158e7931f94SStefano Zampini 4159e7931f94SStefano Zampini /* 4160e7931f94SStefano Zampini Restrict work on active processes only. 4161e7931f94SStefano Zampini */ 4162e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 4163e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 4164e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 41652b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 4166d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4167e7931f94SStefano Zampini if (color) { 4168e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4169e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4170e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4171c8587f34SStefano Zampini } else { 417252e5ac9dSStefano Zampini Mat subdomain_adj; 417352e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 417452e5ac9dSStefano Zampini MatPartitioning partitioner; 417552e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 417652e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 4177b0c7d250SStefano Zampini PetscBool aggregate; 4178b0c7d250SStefano Zampini 4179306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 4180785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 4181e7931f94SStefano Zampini prank = rank; 4182306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 41838002ef2cSStefano Zampini /* 4184e7931f94SStefano Zampini for (i=0;i<size;i++) { 4185e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 4186c8587f34SStefano Zampini } 41878002ef2cSStefano Zampini */ 4188e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4189e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4190c8587f34SStefano Zampini } 4191e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4192b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 4193b0c7d250SStefano Zampini if (aggregate) { 4194b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4195b0c7d250SStefano Zampini PetscMPIInt nrank; 4196b0c7d250SStefano Zampini PetscScalar *vals; 4197b0c7d250SStefano Zampini 4198b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 4199b0c7d250SStefano Zampini lrows = 0; 4200b0c7d250SStefano Zampini if (nrank<redprocs) { 4201b0c7d250SStefano Zampini lrows = size/redprocs; 4202b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4203b0c7d250SStefano Zampini } 42045fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4205b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4206b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4207b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4208b0c7d250SStefano Zampini row = nrank; 4209b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4210b0c7d250SStefano Zampini cols = adjncy; 4211b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4212b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 4213b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 4214b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4215b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 421652e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 421752e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 421852e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4219b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4220b0c7d250SStefano Zampini } else { 4221306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 4222b0c7d250SStefano Zampini } 422322b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 4224e7931f94SStefano Zampini 4225e7931f94SStefano Zampini /* Partition */ 4226306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 4227e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 4228e7931f94SStefano Zampini if (use_vwgt) { 42293837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 4230e7931f94SStefano Zampini v_wgt[0] = local_size; 4231e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 4232c8587f34SStefano Zampini } 423328143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 423428143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 4235e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 4236e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 423722b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 4238e7931f94SStefano Zampini 423952e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 424052e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 424152e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 424252e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4243b0c7d250SStefano Zampini if (!redprocs) { 4244b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 424528143c3dSStefano Zampini } else { 4246b0c7d250SStefano Zampini PetscInt idxs[1]; 4247b0c7d250SStefano Zampini PetscMPIInt tag; 4248b0c7d250SStefano Zampini MPI_Request *reqs; 4249b0c7d250SStefano Zampini 4250b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 4251b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 4252b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 4253b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 425428143c3dSStefano Zampini } 4255b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 4256b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4257b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 4258b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 4259e7931f94SStefano Zampini } 426052e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4261e7931f94SStefano Zampini /* clean up */ 4262e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 426352e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 4264e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 4265e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 4266e7931f94SStefano Zampini } 4267e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 4268e7931f94SStefano Zampini 4269e7931f94SStefano Zampini /* assemble parallel IS for sends */ 4270e7931f94SStefano Zampini i = 1; 4271e7931f94SStefano Zampini if (color) i=0; 4272e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 4273e7931f94SStefano Zampini /* get back IS */ 4274e7931f94SStefano Zampini *is_sends = ranks_send_to; 4275e7931f94SStefano Zampini PetscFunctionReturn(0); 4276e7931f94SStefano Zampini } 4277e7931f94SStefano Zampini 4278e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 4279e7931f94SStefano Zampini 4280e7931f94SStefano Zampini #undef __FUNCT__ 4281e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 428253a05cb3SStefano 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[]) 4283e7931f94SStefano Zampini { 428470cf5478SStefano Zampini Mat local_mat; 4285e7931f94SStefano Zampini IS is_sends_internal; 42869d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 428728143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 42889d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 4289e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 4290e7931f94SStefano Zampini PetscInt* l2gmap_indices; 4291e7931f94SStefano Zampini const PetscInt* is_indices; 4292e7931f94SStefano Zampini MatType new_local_type; 4293e7931f94SStefano Zampini /* buffers */ 4294e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 429528143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 42969d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 4297e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 4298e7931f94SStefano Zampini /* MPI */ 429928143c3dSStefano Zampini MPI_Comm comm,comm_n; 430028143c3dSStefano Zampini PetscSubcomm subcomm; 4301e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 430228143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 430328143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 430428143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 430528143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 430628143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 4307e7931f94SStefano Zampini PetscErrorCode ierr; 4308e7931f94SStefano Zampini 4309e7931f94SStefano Zampini PetscFunctionBegin; 431028143c3dSStefano Zampini /* TODO: add missing checks */ 431128143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 431228143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 431328143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 431428143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 4315e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 431628143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 4317e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4318e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 4319e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 4320e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 4321e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 432228143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 432370cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 432470cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 432528143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 432670cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 432770cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 432870cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 432970cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 433070cf5478SStefano Zampini } 4331e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4332e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4333e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4334e7931f94SStefano Zampini if (!is_sends) { 433528143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4336b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4337c8587f34SStefano Zampini } else { 4338e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4339e7931f94SStefano Zampini is_sends_internal = is_sends; 4340c8587f34SStefano Zampini } 4341e7931f94SStefano Zampini 4342e7931f94SStefano Zampini /* get comm */ 4343a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4344e7931f94SStefano Zampini 4345e7931f94SStefano Zampini /* compute number of sends */ 4346e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4347e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4348e7931f94SStefano Zampini 4349e7931f94SStefano Zampini /* compute number of receives */ 4350e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4351785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4352e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4353e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4354e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4355e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4356e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4357e7931f94SStefano Zampini 435828143c3dSStefano Zampini /* restrict comm if requested */ 435928143c3dSStefano Zampini subcomm = 0; 436028143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 436128143c3dSStefano Zampini if (restrict_comm) { 4362779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4363779c1cceSStefano Zampini 436428143c3dSStefano Zampini color = 0; 436553a05cb3SStefano Zampini if (restrict_full) { 436653a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 436753a05cb3SStefano Zampini } else { 436853a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 436953a05cb3SStefano Zampini } 437028143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 437128143c3dSStefano Zampini subcommsize = commsize - subcommsize; 437228143c3dSStefano Zampini /* check if reuse has been requested */ 437328143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 437428143c3dSStefano Zampini if (*mat_n) { 437528143c3dSStefano Zampini PetscMPIInt subcommsize2; 437628143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 437728143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 437828143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 437928143c3dSStefano Zampini } else { 438028143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 438128143c3dSStefano Zampini } 438228143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4383779c1cceSStefano Zampini PetscMPIInt rank; 4384779c1cceSStefano Zampini 4385779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 438628143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 438728143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 438828143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4389306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 439028143c3dSStefano Zampini } 439128143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 439228143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 439328143c3dSStefano Zampini } else { 439428143c3dSStefano Zampini comm_n = comm; 439528143c3dSStefano Zampini } 439628143c3dSStefano Zampini 4397e7931f94SStefano Zampini /* prepare send/receive buffers */ 4398785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4399e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4400785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4401e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 440228143c3dSStefano Zampini if (nis) { 4403854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 440428143c3dSStefano Zampini } 4405e7931f94SStefano Zampini 440628143c3dSStefano Zampini /* Get data from local matrices */ 4407e7931f94SStefano Zampini if (!isdense) { 4408a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4409e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4410e7931f94SStefano Zampini /* 4411e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4412e7931f94SStefano Zampini send_buffer_idxs should contain: 4413e7931f94SStefano Zampini - MatType_PRIVATE type 4414e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4415e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4416e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4417e7931f94SStefano Zampini */ 4418e7931f94SStefano Zampini } else { 4419e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 44203bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4421854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4422e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4423e7931f94SStefano Zampini send_buffer_idxs[1] = i; 44243bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4425e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 44263bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4427e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4428e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4429e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4430e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4431c8587f34SStefano Zampini } 4432c8587f34SStefano Zampini } 4433e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 443428143c3dSStefano Zampini /* additional is (if any) */ 443528143c3dSStefano Zampini if (nis) { 443628143c3dSStefano Zampini PetscMPIInt psum; 443728143c3dSStefano Zampini PetscInt j; 443828143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 443928143c3dSStefano Zampini PetscInt plen; 444028143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 444128143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 444228143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 444328143c3dSStefano Zampini } 4444854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 444528143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 444628143c3dSStefano Zampini PetscInt plen; 444728143c3dSStefano Zampini const PetscInt *is_array_idxs; 444828143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 444928143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 445028143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 445128143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 445228143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 445328143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 445428143c3dSStefano Zampini } 445528143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 445628143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 445728143c3dSStefano Zampini } 445828143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 445928143c3dSStefano Zampini } 446028143c3dSStefano Zampini 4461e7931f94SStefano Zampini buf_size_idxs = 0; 4462e7931f94SStefano Zampini buf_size_vals = 0; 446328143c3dSStefano Zampini buf_size_idxs_is = 0; 4464e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4465e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4466e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 446728143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4468e7931f94SStefano Zampini } 4469785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4470785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 447195ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4472e7931f94SStefano Zampini 4473e7931f94SStefano Zampini /* get new tags for clean communications */ 4474e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4475e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 447628143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4477e7931f94SStefano Zampini 4478e7931f94SStefano Zampini /* allocate for requests */ 4479785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4480785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 448195ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4482785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4483785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 448495ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4485e7931f94SStefano Zampini 4486e7931f94SStefano Zampini /* communications */ 4487e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4488e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 448928143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4490e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4491e7931f94SStefano Zampini source_dest = onodes[i]; 4492e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4493e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4494e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4495e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 449628143c3dSStefano Zampini if (nis) { 449728143c3dSStefano 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); 449828143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 449928143c3dSStefano Zampini } 4500e7931f94SStefano Zampini } 4501e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4502e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4503e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4504e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 450528143c3dSStefano Zampini if (nis) { 450628143c3dSStefano 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); 450728143c3dSStefano Zampini } 4508e7931f94SStefano Zampini } 4509e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4510e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4511e7931f94SStefano Zampini 4512e7931f94SStefano Zampini /* assemble new l2g map */ 4513e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4514e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45159d30be91SStefano Zampini new_local_rows = 0; 4516e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45179d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4518e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4519e7931f94SStefano Zampini } 45209d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4521e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45229d30be91SStefano Zampini new_local_rows = 0; 4523e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45249d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 45259d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4526e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4527e7931f94SStefano Zampini } 45289d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 45299d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4530e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4531e7931f94SStefano Zampini 4532e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4533e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4534e7931f94SStefano 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) */ 4535e7931f94SStefano Zampini if (n_recvs) { 453628143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4537e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4538e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4539e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4540e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4541e7931f94SStefano Zampini break; 4542e7931f94SStefano Zampini } 4543e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4544e7931f94SStefano Zampini } 4545e7931f94SStefano Zampini switch (new_local_type_private) { 454628143c3dSStefano Zampini case MATDENSE_PRIVATE: 454728143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4548e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4549e7931f94SStefano Zampini bs = 1; 455028143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 455128143c3dSStefano Zampini new_local_type = MATSEQDENSE; 455228143c3dSStefano Zampini bs = 1; 455328143c3dSStefano Zampini } 4554e7931f94SStefano Zampini break; 4555e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4556e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4557e7931f94SStefano Zampini bs = 1; 4558e7931f94SStefano Zampini break; 4559e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4560e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4561e7931f94SStefano Zampini break; 4562e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4563e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4564e7931f94SStefano Zampini break; 4565e7931f94SStefano Zampini default: 45669d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4567e7931f94SStefano Zampini break; 4568e7931f94SStefano Zampini } 456928143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 457028143c3dSStefano Zampini new_local_type = MATSEQDENSE; 457128143c3dSStefano Zampini bs = 1; 4572e7931f94SStefano Zampini } 4573e7931f94SStefano Zampini 457470cf5478SStefano Zampini /* create MATIS object if needed */ 457570cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4576e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4577e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 457870cf5478SStefano Zampini } else { 457970cf5478SStefano Zampini /* it also destroys the local matrices */ 458070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 458170cf5478SStefano Zampini } 458270cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4583e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 45849d30be91SStefano Zampini 45859d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 45869d30be91SStefano Zampini 45879d30be91SStefano Zampini /* Global to local map of received indices */ 45889d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 45899d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 45909d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 45919d30be91SStefano Zampini 45929d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 45939d30be91SStefano Zampini buf_size_idxs = 0; 45949d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 45959d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 45969d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 45979d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 45989d30be91SStefano Zampini } 45999d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 46009d30be91SStefano Zampini 46019d30be91SStefano Zampini /* set preallocation */ 46029d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 46039d30be91SStefano Zampini if (!newisdense) { 46049d30be91SStefano Zampini PetscInt *new_local_nnz=0; 46059d30be91SStefano Zampini 46069d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 46079d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 46089d30be91SStefano Zampini if (n_recvs) { 46099d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 46109d30be91SStefano Zampini } 46119d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 46129d30be91SStefano Zampini PetscInt j; 46139d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 46149d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 46159d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 46169d30be91SStefano Zampini } 46179d30be91SStefano Zampini } else { 46189d30be91SStefano Zampini /* TODO */ 46199d30be91SStefano Zampini } 46209d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 46219d30be91SStefano Zampini } 46229d30be91SStefano Zampini if (new_local_nnz) { 46239d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 46249d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 46259d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 46269d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46279d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 46289d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46299d30be91SStefano Zampini } else { 46309d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46319d30be91SStefano Zampini } 46329d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 46339d30be91SStefano Zampini } else { 46349d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46359d30be91SStefano Zampini } 4636e7931f94SStefano Zampini 4637e7931f94SStefano Zampini /* set values */ 4638e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 46399d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 4640e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4641e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 4642e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 46439d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 4644e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4645e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4646e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 464728143c3dSStefano Zampini } else { 464828143c3dSStefano Zampini /* TODO */ 4649e7931f94SStefano Zampini } 4650e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4651e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 4652e7931f94SStefano Zampini } 4653e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4654e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 465570cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 465670cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46579d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 46589d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 4659e7931f94SStefano Zampini 4660dfd14d43SStefano Zampini #if 0 466128143c3dSStefano Zampini if (!restrict_comm) { /* check */ 4662e7931f94SStefano Zampini Vec lvec,rvec; 4663e7931f94SStefano Zampini PetscReal infty_error; 4664e7931f94SStefano Zampini 46652a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 4666e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 4667e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 4668e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 466970cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 4670e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4671e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 4672e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 4673e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 4674e7931f94SStefano Zampini } 467528143c3dSStefano Zampini #endif 4676e7931f94SStefano Zampini 467728143c3dSStefano Zampini /* assemble new additional is (if any) */ 467828143c3dSStefano Zampini if (nis) { 467928143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 468028143c3dSStefano Zampini 468128143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4682854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 468328143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 468428143c3dSStefano Zampini psum = 0; 468528143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 468628143c3dSStefano Zampini for (j=0;j<nis;j++) { 468728143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 468828143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 468928143c3dSStefano Zampini psum += plen; 469028143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 469128143c3dSStefano Zampini } 469228143c3dSStefano Zampini } 4693854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 4694854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 469528143c3dSStefano Zampini for (i=1;i<nis;i++) { 469628143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 469728143c3dSStefano Zampini } 469828143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 469928143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 470028143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 470128143c3dSStefano Zampini for (j=0;j<nis;j++) { 470228143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 470328143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 470428143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 470528143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 470628143c3dSStefano Zampini } 470728143c3dSStefano Zampini } 470828143c3dSStefano Zampini for (i=0;i<nis;i++) { 470928143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 471028143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 471128143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 471228143c3dSStefano Zampini } 471328143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 471428143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 471528143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 471628143c3dSStefano Zampini } 4717e7931f94SStefano Zampini /* free workspace */ 471828143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4719e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4720e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4721e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4722e7931f94SStefano Zampini if (isdense) { 4723e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4724e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4725e7931f94SStefano Zampini } else { 4726e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4727e7931f94SStefano Zampini } 472828143c3dSStefano Zampini if (nis) { 472928143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 473028143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 473128143c3dSStefano Zampini } 4732e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4733e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 473428143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4735e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4736e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 473728143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4738e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4739e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4740e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4741e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4742e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 474328143c3dSStefano Zampini if (nis) { 474428143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 474528143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 474628143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 474728143c3dSStefano Zampini } 474828143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 474928143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 475028143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 475128143c3dSStefano Zampini for (i=0;i<nis;i++) { 475228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 475328143c3dSStefano Zampini } 475453a05cb3SStefano Zampini *mat_n = NULL; 475528143c3dSStefano Zampini } 4756e7931f94SStefano Zampini PetscFunctionReturn(0); 4757e7931f94SStefano Zampini } 4758a57a6d2fSStefano Zampini 475912edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4760af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 476112edc857SStefano Zampini 4762c8587f34SStefano Zampini #undef __FUNCT__ 4763c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4764c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4765c8587f34SStefano Zampini { 4766c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4767c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 476820a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 47699881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 477020a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 47716e683305SStefano Zampini IS coarse_is,*isarray; 47726e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 4773*30368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 4774f9eb5b7dSStefano Zampini PC pc_temp; 4775c8587f34SStefano Zampini PCType coarse_pc_type; 4776c8587f34SStefano Zampini KSPType coarse_ksp_type; 4777f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 47784f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 47796e683305SStefano Zampini Mat t_coarse_mat_is; 47806e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 47816e683305SStefano Zampini PetscMPIInt all_procs; 478274e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 478368457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 478422bc73bbSStefano Zampini PetscScalar *array; 47859881197aSStefano Zampini PetscErrorCode ierr; 4786fdc09c96SStefano Zampini 4787c8587f34SStefano Zampini PetscFunctionBegin; 4788c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 478968457ee5SStefano 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 */ 4790fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 47915a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4792fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4793f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4794f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4795f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4796fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 479751bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 479851bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4799dc4bcba2SStefano Zampini PC pc; 4800dc4bcba2SStefano Zampini PetscBool isbddc; 4801dc4bcba2SStefano Zampini 4802dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4803dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4804dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4805dc4bcba2SStefano Zampini if (isbddc) { 4806dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4807dc4bcba2SStefano Zampini } 4808727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4809fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4810fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4811fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4812f4ddd8eeSStefano Zampini } 4813fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4814fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4815f4ddd8eeSStefano Zampini } 481670cf5478SStefano Zampini /* reset any subassembling information */ 481770cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 48186e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 48196e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4820fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4821f4ddd8eeSStefano Zampini } 4822c8587f34SStefano Zampini 48236e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 48242b510759SStefano Zampini im_active = !!(pcis->n); 48252b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 48266e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 48276e683305SStefano Zampini void_procs = all_procs-active_procs; 48286e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 482974e2c79eSStefano Zampini redist = PETSC_FALSE; 483022bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 48316e683305SStefano Zampini csin_ml = PETSC_TRUE; 48326e683305SStefano Zampini ncoarse_ml = void_procs; 4833779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4834779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 48356e683305SStefano Zampini csin_ds = PETSC_TRUE; 483618a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 483718a45a71SStefano Zampini redist = PETSC_TRUE; 483818a45a71SStefano Zampini } else { 48396e683305SStefano Zampini csin_ds = PETSC_TRUE; 4840779c1cceSStefano Zampini ncoarse_ds = active_procs; 4841779c1cceSStefano Zampini redist = PETSC_TRUE; 484218a45a71SStefano Zampini } 48436e683305SStefano Zampini } else { 48446e683305SStefano Zampini csin_ml = PETSC_FALSE; 48456e683305SStefano Zampini ncoarse_ml = all_procs; 48466e683305SStefano Zampini if (void_procs) { 48476e683305SStefano Zampini csin_ds = PETSC_TRUE; 48486e683305SStefano Zampini ncoarse_ds = void_procs; 48496e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 48506e683305SStefano Zampini } else { 4851779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 485274e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 485374e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 485474e2c79eSStefano Zampini redist = PETSC_TRUE; 485574e2c79eSStefano Zampini } else { 48566e683305SStefano Zampini csin_ds = PETSC_FALSE; 48576e683305SStefano Zampini ncoarse_ds = all_procs; 48586e683305SStefano Zampini } 48596e683305SStefano Zampini } 486074e2c79eSStefano Zampini } 48616e683305SStefano Zampini 48626e683305SStefano Zampini /* 48636e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 48646e683305SStefano Zampini - we have not exceeded the number of levels requested 48656e683305SStefano Zampini - we can actually subassemble the active processes 48666e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 48676e683305SStefano Zampini */ 48686e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 48696e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 48706e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 48716e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 48726e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4873f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 48742b510759SStefano Zampini } else { 4875f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4876c8587f34SStefano Zampini } 4877c8587f34SStefano Zampini } 48786e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 48796e683305SStefano Zampini if (multilevel_allowed) { 48806e683305SStefano Zampini ncoarse = ncoarse_ml; 48816e683305SStefano Zampini csin = csin_ml; 488258da7f69SStefano Zampini redist = PETSC_FALSE; 48836e683305SStefano Zampini } else { 48846e683305SStefano Zampini ncoarse = ncoarse_ds; 48856e683305SStefano Zampini csin = csin_ds; 48866e683305SStefano Zampini } 4887e7931f94SStefano Zampini 4888abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4889abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4890abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4891abbbba34SStefano Zampini 4892abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 489322bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 489422bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 489522bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 489622bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4897b1ecc7b1SStefano Zampini #if 0 4898b9b85e73SStefano Zampini { 4899b9b85e73SStefano Zampini PetscViewer viewer; 4900b9b85e73SStefano Zampini char filename[256]; 4901b1ecc7b1SStefano Zampini sprintf(filename,"local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4902b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4903b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4904b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 4905b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4906b9b85e73SStefano Zampini } 4907b9b85e73SStefano Zampini #endif 4908e176bc59SStefano 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); 49096e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 49106e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49116e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4912abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4913abbbba34SStefano Zampini 49146e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 4915*30368db7SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local))) { /* protects from unneded computations */ 49166e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 49176e683305SStefano Zampini const PetscInt *idxs; 49186e683305SStefano Zampini ISLocalToGlobalMapping tmap; 49196e683305SStefano Zampini 49206e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 49210be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 49226e683305SStefano Zampini /* allocate space for temporary storage */ 4923854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4924854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 49256e683305SStefano Zampini /* allocate for IS array */ 49266e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 49276e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 4928*30368db7SStefano Zampini nisvert = 0; 4929*30368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 4930*30368db7SStefano Zampini nisvert = 1; 4931*30368db7SStefano Zampini } 4932*30368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 4933854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 49346e683305SStefano Zampini /* dofs splitting */ 49356e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 49366e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 49376e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 49386e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49396e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49406e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49416e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 4942*30368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 49436e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 49446e683305SStefano Zampini } 49456e683305SStefano Zampini /* neumann boundaries */ 49466e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 49476e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 49486e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 49496e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49506e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49516e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49526e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 4953*30368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 49546e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 49556e683305SStefano Zampini } 4956*30368db7SStefano Zampini /* primal vertices (benign) */ 4957*30368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 4958*30368db7SStefano Zampini ierr = ISGetLocalSize(pcbddc->user_primal_vertices_local,&tsize);CHKERRQ(ierr); 4959*30368db7SStefano Zampini ierr = ISGetIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 4960*30368db7SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 4961*30368db7SStefano Zampini ierr = ISRestoreIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 4962*30368db7SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 4963*30368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nis-1]);CHKERRQ(ierr); 4964*30368db7SStefano Zampini } 49656e683305SStefano Zampini /* free memory */ 49666e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 49676e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 49686e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 49696e683305SStefano Zampini } else { 49706e683305SStefano Zampini nis = 0; 49716e683305SStefano Zampini nisdofs = 0; 49726e683305SStefano Zampini nisneu = 0; 4973*30368db7SStefano Zampini nisvert = 0; 49746e683305SStefano Zampini isarray = NULL; 49756e683305SStefano Zampini } 49766e683305SStefano Zampini /* destroy no longer needed map */ 49776e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 49786e683305SStefano Zampini 49796e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 49806e683305SStefano Zampini coarse_mat_is = NULL; 49816e683305SStefano Zampini if (csin) { 49826e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 498374e2c79eSStefano Zampini if (redist) { 498474e2c79eSStefano Zampini PetscMPIInt rank; 4985779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 498674e2c79eSStefano Zampini 498774e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 498858da7f69SStefano Zampini spc = active_procs/ncoarse; 498958da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 4990779c1cceSStefano Zampini if (im_active) { 4991779c1cceSStefano Zampini destsize = 1; 499274e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 499374e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 499474e2c79eSStefano Zampini } else { 499574e2c79eSStefano Zampini dest[0] = rank/(spc+1); 499674e2c79eSStefano Zampini } 499774e2c79eSStefano Zampini } else { 4998779c1cceSStefano Zampini destsize = 0; 49996e683305SStefano Zampini } 5000779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5001779c1cceSStefano Zampini } else if (csin_type_simple) { 50026e683305SStefano Zampini PetscMPIInt rank; 50036e683305SStefano Zampini PetscInt issize,isidx; 5004779c1cceSStefano Zampini 50056e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 50066e683305SStefano Zampini if (im_active) { 50076e683305SStefano Zampini issize = 1; 50086e683305SStefano Zampini isidx = (PetscInt)rank; 50096e683305SStefano Zampini } else { 50106e683305SStefano Zampini issize = 0; 50116e683305SStefano Zampini isidx = -1; 50126e683305SStefano Zampini } 50136e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5014779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 5015b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 50166e683305SStefano Zampini } 5017779c1cceSStefano Zampini 5018779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 5019779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 5020779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 5021779c1cceSStefano Zampini PetscInt *coarse_candidates; 5022779c1cceSStefano Zampini const PetscInt* tisindices; 5023779c1cceSStefano Zampini 5024779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 5025779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 5026779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5027779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 5028779c1cceSStefano Zampini if (!coarse_candidates[i]) { 5029779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 5030779c1cceSStefano Zampini } 5031779c1cceSStefano Zampini } 5032779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 5033779c1cceSStefano Zampini 5034779c1cceSStefano Zampini 50356e683305SStefano Zampini if (pcbddc->dbg_flag) { 50366e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50376e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 50386e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50396e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 5040779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 50416e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 50426e683305SStefano Zampini } 50436e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 50446e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50456e683305SStefano Zampini } 50466e683305SStefano Zampini /* shift the pattern on coarse candidates */ 50476e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 50486e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 5049854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 50506e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 50516e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 50526e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 50536e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 50546e683305SStefano Zampini } 50556e683305SStefano Zampini if (pcbddc->dbg_flag) { 50566e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50576e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 50586e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50596e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50606e683305SStefano Zampini } 5061779c1cceSStefano Zampini } 50626e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 506353a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 506453a05cb3SStefano 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); 506553a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 506653a05cb3SStefano 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); 506753a05cb3SStefano Zampini } 50686e683305SStefano Zampini } else { 50696e683305SStefano Zampini if (pcbddc->dbg_flag) { 50706e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50716e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 50726e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50736e683305SStefano Zampini } 50746e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 50756e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 50766e683305SStefano Zampini } 50776e683305SStefano Zampini 50786e683305SStefano Zampini /* create local to global scatters for coarse problem */ 507968457ee5SStefano Zampini if (compute_vecs) { 50806e683305SStefano Zampini PetscInt lrows; 50816e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 50826e683305SStefano Zampini if (coarse_mat_is) { 50836e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 50846e683305SStefano Zampini } else { 50856e683305SStefano Zampini lrows = 0; 50866e683305SStefano Zampini } 50876e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 50886e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 50896e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 50906e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 50916e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 50926e683305SStefano Zampini } 50936e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 50946e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 5095c8587f34SStefano Zampini 5096f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5097f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5098f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5099f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5100f9eb5b7dSStefano Zampini } else { 5101f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5102f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5103c8587f34SStefano Zampini } 5104c8587f34SStefano Zampini 51056e683305SStefano Zampini /* print some info if requested */ 51066e683305SStefano Zampini if (pcbddc->dbg_flag) { 51076e683305SStefano Zampini if (!multilevel_allowed) { 51086e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 51096e683305SStefano Zampini if (multilevel_requested) { 51106e683305SStefano 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); 51116e683305SStefano Zampini } else if (pcbddc->max_levels) { 51126e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 51136e683305SStefano Zampini } 51146e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 51156e683305SStefano Zampini } 51166e683305SStefano Zampini } 51176e683305SStefano Zampini 5118f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 51196e683305SStefano Zampini if (coarse_mat_is) { 51206e683305SStefano Zampini MatReuse coarse_mat_reuse; 51216a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 51226e683305SStefano Zampini if (pcbddc->dbg_flag) { 51236e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 51246e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 51256e683305SStefano Zampini } 5126f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5127312be037SStefano Zampini char prefix[256],str_level[16]; 5128e604994aSStefano Zampini size_t len; 51296e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5130422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5131c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5132f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 51335f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 5134c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 51356e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5136c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5137c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5138e604994aSStefano Zampini /* prefix */ 5139e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5140e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5141e604994aSStefano Zampini if (!pcbddc->current_level) { 5142e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5143e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5144c8587f34SStefano Zampini } else { 5145e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5146312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5147312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 514834d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5149312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5150e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5151e604994aSStefano Zampini } 5152e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 51533e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 51543e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 51553e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 51563e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5157f9eb5b7dSStefano Zampini /* allow user customization */ 5158f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 51593e3c6dadSStefano Zampini } 51603e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 516151bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 51623e3c6dadSStefano Zampini if (nisdofs) { 51633e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 51643e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 51653e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 51663e3c6dadSStefano Zampini } 51673e3c6dadSStefano Zampini } 51683e3c6dadSStefano Zampini if (nisneu) { 51693e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 51703e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5171312be037SStefano Zampini } 5172*30368db7SStefano Zampini if (nisvert) { 5173*30368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 5174*30368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 5175*30368db7SStefano Zampini } 5176f9eb5b7dSStefano Zampini 5177f9eb5b7dSStefano Zampini /* get some info after set from options */ 5178f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5179f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 51804f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 51816e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5182f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5183f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5184f9eb5b7dSStefano Zampini } 518539f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 51864f3a063dSStefano Zampini if (isredundant) { 51874f3a063dSStefano Zampini KSP inner_ksp; 51884f3a063dSStefano Zampini PC inner_pc; 51894f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 51904f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 51914f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 51924f3a063dSStefano Zampini } 5193f9eb5b7dSStefano Zampini 5194f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 5195fa7f1dd8SStefano Zampini if (coarse_reuse) { 519681d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 5197fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 51986e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 5199fa7f1dd8SStefano Zampini } else { 52006e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 5201fa7f1dd8SStefano Zampini } 5202c8587f34SStefano Zampini if (isbddc || isnn) { 520322bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 520470cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 5205b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 520622b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 52076e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 52086e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 52096e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 52106e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 521122b6e8a2SStefano Zampini } 521270cf5478SStefano Zampini } 521353a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 521470cf5478SStefano Zampini } else { 521522bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 521622bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 521722bc73bbSStefano Zampini } 521822bc73bbSStefano Zampini } else { 52192e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 5220c8587f34SStefano Zampini } 5221c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 5222c8587f34SStefano Zampini 52233301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 52245a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 52253301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 52263301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 52273301b35fSStefano Zampini } 52283301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 52293301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 52303301b35fSStefano Zampini } 52313301b35fSStefano Zampini if (pc->pmat->spd_set) { 52323301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 52333301b35fSStefano Zampini } 52346e683305SStefano Zampini /* set operators */ 52355f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 52366e683305SStefano Zampini if (pcbddc->dbg_flag) { 52376e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 52386e683305SStefano Zampini } 52396e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 52406e683305SStefano Zampini coarse_mat = 0; 52416e683305SStefano Zampini } 52426e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5243b1ecc7b1SStefano Zampini #if 0 5244b9b85e73SStefano Zampini { 5245b9b85e73SStefano Zampini PetscViewer viewer; 5246b9b85e73SStefano Zampini char filename[256]; 5247b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5248b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 5249b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5250b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5251b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5252b9b85e73SStefano Zampini } 5253b9b85e73SStefano Zampini #endif 5254c8587f34SStefano Zampini 5255c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 5256298c0119SStefano Zampini #if 0 5257c8587f34SStefano Zampini if (pcbddc->NullSpace) { 5258c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 525998a51de6SStefano Zampini } 5260298c0119SStefano Zampini #endif 5261b0f5fe93SStefano Zampini /* hack */ 526298a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 526398a51de6SStefano Zampini Vec crhs,csol; 526404708bb6SStefano Zampini 5265f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 5266f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 5267f347579bSStefano Zampini if (!csol) { 52682a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 5269f9eb5b7dSStefano Zampini } 5270f347579bSStefano Zampini if (!crhs) { 52712a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 5272f347579bSStefano Zampini } 5273b0f5fe93SStefano Zampini } 5274b0f5fe93SStefano Zampini 5275b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 5276b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 5277b0f5fe93SStefano Zampini 5278b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 52794f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 52804f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 52814f1b2e48SStefano Zampini } 5282b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 5283b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 5284b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5285b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5286b0f5fe93SStefano Zampini if (coarse_mat) { 5287b0f5fe93SStefano Zampini Vec nullv; 5288b0f5fe93SStefano Zampini PetscScalar *array,*array2; 5289b0f5fe93SStefano Zampini PetscInt nl; 5290b0f5fe93SStefano Zampini 5291b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 5292b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 5293b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5294b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 5295b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 5296b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 5297b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5298b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 5299b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 5300b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 5301b0f5fe93SStefano Zampini } 5302b0f5fe93SStefano Zampini } 5303b0f5fe93SStefano Zampini 5304b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 5305b0f5fe93SStefano Zampini PetscBool ispreonly; 5306b0f5fe93SStefano Zampini 5307b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5308b0f5fe93SStefano Zampini PetscBool isnull; 5309b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 5310b0f5fe93SStefano Zampini if (isnull) { 5311*30368db7SStefano Zampini if (isbddc && !pcbddc->benign_saddle_point) { 5312b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 5313b0f5fe93SStefano Zampini } else { 5314b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 5315b0f5fe93SStefano Zampini } 5316b0f5fe93SStefano Zampini } else { 5317b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5318b0f5fe93SStefano Zampini } 5319b0f5fe93SStefano Zampini } 5320b0f5fe93SStefano Zampini /* setup coarse ksp */ 5321b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 5322cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 5323cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 53246e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 5325c8587f34SStefano Zampini KSP check_ksp; 53262b510759SStefano Zampini KSPType check_ksp_type; 5327c8587f34SStefano Zampini PC check_pc; 53286e683305SStefano Zampini Vec check_vec,coarse_vec; 53296a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 53302b510759SStefano Zampini PetscInt its; 53316e683305SStefano Zampini PetscBool compute_eigs; 53326e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 53336e683305SStefano Zampini PetscInt neigs; 53348e185a42SStefano Zampini const char *prefix; 5335c8587f34SStefano Zampini 53362b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 53376e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 5338422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 533923ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5340f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 53412b510759SStefano Zampini if (ispreonly) { 53422b510759SStefano Zampini check_ksp_type = KSPPREONLY; 53436e683305SStefano Zampini compute_eigs = PETSC_FALSE; 53442b510759SStefano Zampini } else { 5345cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 53466e683305SStefano Zampini compute_eigs = PETSC_TRUE; 5347c8587f34SStefano Zampini } 5348c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 53496e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 53506e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 53516e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5352a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5353a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5354a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5355a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5356c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5357c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5358c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5359c8587f34SStefano Zampini /* create random vec */ 53606e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 53616e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5362c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5363c8587f34SStefano Zampini if (CoarseNullSpace) { 5364c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5365c8587f34SStefano Zampini } 53666e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5367c8587f34SStefano Zampini /* solve coarse problem */ 53686e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5369c8587f34SStefano Zampini if (CoarseNullSpace) { 53706e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5371c8587f34SStefano Zampini } 5372cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 53736e683305SStefano Zampini if (compute_eigs) { 5374854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5375854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 53766e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 53776e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 53786e683305SStefano Zampini lambda_min = eigs_r[0]; 53796e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 53806e683305SStefano Zampini if (lambda_max>lambda_min) { 5381cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5382cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5383cbcc2c2aSStefano Zampini } 5384c8587f34SStefano Zampini } 5385c8587f34SStefano Zampini } 5386cbcc2c2aSStefano Zampini 5387c8587f34SStefano Zampini /* check coarse problem residual error */ 53886e683305SStefano Zampini if (pcbddc->dbg_flag) { 53896e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 53906e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 53916e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5392c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 53936e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 53946e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5395c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5396779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 53976e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 53986e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 53996e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 54006e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5401b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5402b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5403b0f5fe93SStefano Zampini } 54046e683305SStefano Zampini if (compute_eigs) { 54056e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5406deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5407c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 54086e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 54096e683305SStefano 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); 54106e683305SStefano Zampini for (i=0;i<neigs;i++) { 54116e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5412c8587f34SStefano Zampini } 54136e683305SStefano Zampini } 54146e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 54156e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 54166e683305SStefano Zampini } 5417c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 54186e683305SStefano Zampini if (compute_eigs) { 54196e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 54206e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5421c8587f34SStefano Zampini } 54226e683305SStefano Zampini } 54236e683305SStefano Zampini } 5424cbcc2c2aSStefano Zampini /* print additional info */ 5425cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 54266e683305SStefano Zampini /* waits until all processes reaches this point */ 54276e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5428cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5429cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5430cbcc2c2aSStefano Zampini } 5431cbcc2c2aSStefano Zampini 54322b510759SStefano Zampini /* free memory */ 5433c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5434fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5435c8587f34SStefano Zampini PetscFunctionReturn(0); 5436c8587f34SStefano Zampini } 5437674ae819SStefano Zampini 5438f34684f1SStefano Zampini #undef __FUNCT__ 5439f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5440f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5441f34684f1SStefano Zampini { 5442f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5443f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5444f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5445dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5446dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 544773be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5448dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5449f34684f1SStefano Zampini PetscErrorCode ierr; 5450f34684f1SStefano Zampini 5451f34684f1SStefano Zampini PetscFunctionBegin; 5452f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 54530e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 54540e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5455727cdba6SStefano Zampini } 5456dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 54573bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5458dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5459dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5460dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5461dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5462dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5463dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 54640e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 54650e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 54660e6343abSStefano Zampini } 5467dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5468dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5469dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5470dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5471dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5472f34684f1SStefano Zampini 5473f34684f1SStefano Zampini /* check numbering */ 5474f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5475019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5476dc456d91SStefano Zampini PetscInt i; 5477b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5478f34684f1SStefano Zampini 5479f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5480f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5481f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 54820fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 5483019a44ceSStefano Zampini /* counter */ 5484019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5485019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5486019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5487019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5488019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5489019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5490019a44ceSStefano Zampini 5491f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5492f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5493727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5494f34684f1SStefano Zampini } 5495f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5496f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);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); 5500e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5501e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5502f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5503019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5504f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5505019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 550675c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 550775c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5508b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5509019a44ceSStefano 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); 5510f34684f1SStefano Zampini } 5511f34684f1SStefano Zampini } 5512019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5513b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5514f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5515f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5516f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5517f34684f1SStefano Zampini } 5518f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5519f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5520e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5521e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5522f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5523f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5524b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5525ca8b9ea9SStefano Zampini PetscInt *gidxs; 5526ca8b9ea9SStefano Zampini 5527ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 55283bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5529f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5530f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5531f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5532f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 55334bc2dc4bSStefano 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); 5534f34684f1SStefano Zampini } 5535f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5536ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5537f34684f1SStefano Zampini } 5538f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5539302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5540f34684f1SStefano Zampini } 55418bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5542f34684f1SStefano Zampini /* get back data */ 5543f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5544f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5545674ae819SStefano Zampini PetscFunctionReturn(0); 5546674ae819SStefano Zampini } 5547674ae819SStefano Zampini 5548e456f2a8SStefano Zampini #undef __FUNCT__ 5549e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5550a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5551e456f2a8SStefano Zampini { 5552e456f2a8SStefano Zampini IS localis_t; 5553a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5554e456f2a8SStefano Zampini PetscScalar *vals; 5555e456f2a8SStefano Zampini PetscErrorCode ierr; 5556e456f2a8SStefano Zampini 5557e456f2a8SStefano Zampini PetscFunctionBegin; 5558a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5559e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5560854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5561e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5562e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5563a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5564a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 55651035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5566a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 55671035eff8SStefano Zampini } 5568a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5569e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5570e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5571a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5572a7dc3881SStefano Zampini /* now compute set in local ordering */ 5573a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5574a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5575a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5576a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5577a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5578ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5579e456f2a8SStefano Zampini lsize++; 5580e456f2a8SStefano Zampini } 5581e456f2a8SStefano Zampini } 5582854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5583a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5584ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5585e456f2a8SStefano Zampini idxs[lsize++] = i; 5586e456f2a8SStefano Zampini } 5587e456f2a8SStefano Zampini } 5588a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5589a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5590e456f2a8SStefano Zampini *localis = localis_t; 5591e456f2a8SStefano Zampini PetscFunctionReturn(0); 5592e456f2a8SStefano Zampini } 5593906d46d4SStefano Zampini 5594906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5595906d46d4SStefano Zampini #undef __FUNCT__ 5596906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5597906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5598906d46d4SStefano Zampini { 5599906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5600906d46d4SStefano Zampini PetscErrorCode ierr; 5601906d46d4SStefano Zampini 5602906d46d4SStefano Zampini PetscFunctionBegin; 5603906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5604906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5605906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5606906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5607906d46d4SStefano Zampini PetscFunctionReturn(0); 5608906d46d4SStefano Zampini } 5609906d46d4SStefano Zampini 5610906d46d4SStefano Zampini #undef __FUNCT__ 5611906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5612906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5613906d46d4SStefano Zampini { 5614906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5615906d46d4SStefano Zampini PetscErrorCode ierr; 5616906d46d4SStefano Zampini 5617906d46d4SStefano Zampini PetscFunctionBegin; 5618906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5619906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5620906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5621906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5622906d46d4SStefano Zampini PetscFunctionReturn(0); 5623906d46d4SStefano Zampini } 5624b96c3477SStefano Zampini 5625b96c3477SStefano Zampini #undef __FUNCT__ 5626b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 562708122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5628b96c3477SStefano Zampini { 5629a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5630b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5631b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5632a64f4aa4SStefano Zampini Mat S_j; 5633b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 5634b96c3477SStefano Zampini PetscBool free_used_adj; 5635b96c3477SStefano Zampini PetscErrorCode ierr; 5636b96c3477SStefano Zampini 5637b96c3477SStefano Zampini PetscFunctionBegin; 5638b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 5639b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 564008122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 5641b96c3477SStefano Zampini used_xadj = NULL; 5642b96c3477SStefano Zampini used_adjncy = NULL; 5643b96c3477SStefano Zampini } else { 564408122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 564508122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 564608122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 564708122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 5648b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 5649b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 5650b96c3477SStefano Zampini } else { 56512fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 5652b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 5653b96c3477SStefano Zampini PetscInt nvtxs; 5654b96c3477SStefano Zampini 56552fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 56562fffb893SStefano Zampini if (flg_row) { 5657b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 5658b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 5659b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 5660b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 56612fffb893SStefano Zampini } else { 56622fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 56632fffb893SStefano Zampini used_xadj = NULL; 56642fffb893SStefano Zampini used_adjncy = NULL; 56652fffb893SStefano Zampini } 56662fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 5667b96c3477SStefano Zampini } 5668b96c3477SStefano Zampini } 5669d5574798SStefano Zampini 5670d5574798SStefano Zampini /* setup sub_schurs data */ 5671a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5672a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 5673a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 5674a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 567506a4e24aSStefano 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); 5676a64f4aa4SStefano Zampini } else { 56776816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 567804708bb6SStefano Zampini PetscBool isseqaij; 56795feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 56805feab87aSStefano Zampini PetscInt n_vertices; 56815feab87aSStefano Zampini 56825feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 56832034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 56845feab87aSStefano Zampini } 568504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 568604708bb6SStefano Zampini if (!isseqaij) { 568704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 568804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 568904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 569004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 569104708bb6SStefano Zampini } else { 569204708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 569304708bb6SStefano Zampini } 569404708bb6SStefano Zampini } 569506a4e24aSStefano 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); 5696a64f4aa4SStefano Zampini } 5697a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5698b96c3477SStefano Zampini 5699b96c3477SStefano Zampini /* free adjacency */ 5700b96c3477SStefano Zampini if (free_used_adj) { 5701b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 5702b96c3477SStefano Zampini } 5703b96c3477SStefano Zampini PetscFunctionReturn(0); 5704b96c3477SStefano Zampini } 5705b96c3477SStefano Zampini 5706b96c3477SStefano Zampini #undef __FUNCT__ 5707b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 570808122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 5709b96c3477SStefano Zampini { 5710b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5711b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5712b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5713b96c3477SStefano Zampini PCBDDCGraph graph; 5714b96c3477SStefano Zampini PetscErrorCode ierr; 5715b96c3477SStefano Zampini 5716b96c3477SStefano Zampini PetscFunctionBegin; 5717b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 571808122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 57193301b35fSStefano Zampini IS verticesIS,verticescomm; 57203301b35fSStefano Zampini PetscInt vsize,*idxs; 5721b96c3477SStefano Zampini 5722b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 57233301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 57243301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57253301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 57263301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57273301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 5728b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 57297fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 57303301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 57313301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 5732b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5733b96c3477SStefano Zampini /* 5734b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 5735b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5736b96c3477SStefano Zampini } 5737b96c3477SStefano Zampini */ 5738b96c3477SStefano Zampini } else { 5739b96c3477SStefano Zampini graph = pcbddc->mat_graph; 5740b96c3477SStefano Zampini } 5741b96c3477SStefano Zampini 5742b96c3477SStefano Zampini /* sub_schurs init */ 5743a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 5744a64f4aa4SStefano Zampini 5745b96c3477SStefano Zampini /* free graph struct */ 574608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 5747b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 5748b96c3477SStefano Zampini } 5749b96c3477SStefano Zampini PetscFunctionReturn(0); 5750b96c3477SStefano Zampini } 5751fa34dd3eSStefano Zampini 5752fa34dd3eSStefano Zampini #undef __FUNCT__ 5753fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 5754fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 5755fa34dd3eSStefano Zampini { 5756fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5757fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5758fa34dd3eSStefano Zampini PetscErrorCode ierr; 5759fa34dd3eSStefano Zampini 5760fa34dd3eSStefano Zampini PetscFunctionBegin; 5761fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 5762fa34dd3eSStefano Zampini IS zerodiag = NULL; 57634f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 5764fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 57654f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 576675c01103SStefano Zampini PetscReal norm; 5767fa34dd3eSStefano Zampini PetscInt i; 5768fa34dd3eSStefano Zampini 5769fa34dd3eSStefano Zampini /* B0 and B0_B */ 5770fa34dd3eSStefano Zampini if (zerodiag) { 5771fa34dd3eSStefano Zampini IS dummy; 5772fa34dd3eSStefano Zampini 57734f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 57744f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 5775fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 5776fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 5777fa34dd3eSStefano Zampini } 5778fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 5779fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 5780fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 5781fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5782fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5783fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5784fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5785fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 5786fa34dd3eSStefano Zampini /* S_j */ 5787fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5788fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 5789fa34dd3eSStefano Zampini 5790fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 5791fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 5792fa34dd3eSStefano Zampini /* continuous in primal space */ 5793fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 5794fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5795fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5796fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 57974f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 57984f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 5799fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5800fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5801fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5802fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5803fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5804fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5805fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 5806fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 5807fa34dd3eSStefano Zampini 5808fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 5809fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 5810fa34dd3eSStefano Zampini /* local with Schur */ 5811fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 5812fa34dd3eSStefano Zampini if (zerodiag) { 5813fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 58144f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 5815fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5816fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5817fa34dd3eSStefano Zampini } 5818fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 5819fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5820fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5821fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5822fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5823fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 5824fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5825fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5826fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 5827fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5828fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5829fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5830fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5831fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5832fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 5833fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 5834fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5835fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5836fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5837fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5838fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5839fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5840fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 5841fa34dd3eSStefano Zampini if (zerodiag) { 5842fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 5843fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 58444f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 5845fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5846fa34dd3eSStefano Zampini } 5847fa34dd3eSStefano Zampini /* BDDC */ 5848fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 5849fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 5850fa34dd3eSStefano Zampini 5851fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 5852fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 5853fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 5854fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 58554f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 58564f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 5857fa34dd3eSStefano Zampini } 58584f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 5859fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 5860fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 5861fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 5862fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5863fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 5864fa34dd3eSStefano Zampini } 5865fa34dd3eSStefano Zampini PetscFunctionReturn(0); 5866fa34dd3eSStefano Zampini } 5867