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 698*ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 69908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 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); 707*ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 708f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 709f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 7109ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 711aff50787SStefano Zampini PetscInt j,k; 712aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 713aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 714aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 71508122e43SStefano Zampini } 71608122e43SStefano Zampini for (j=0;j<subset_size;j++) { 717aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 718aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 719aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 720aff50787SStefano Zampini } 72108122e43SStefano Zampini } 72208122e43SStefano Zampini } else { 72308122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 72408122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 72508122e43SStefano Zampini } 7268bec7fa6SStefano Zampini } else { 727f6f667cfSStefano Zampini S = Sarray + cumarray; 728f6f667cfSStefano Zampini St = Starray + cumarray; 7298bec7fa6SStefano Zampini } 73008122e43SStefano Zampini 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 { 7391cf9b237SStefano Zampini if (nmin) { 7401cf9b237SStefano Zampini Mat SM,StM; 7411cf9b237SStefano Zampini PetscInt j,k,nccs,nccst; 7421cf9b237SStefano Zampini 7431cf9b237SStefano Zampini for (j=0;j<subset_size;j++) { 7441cf9b237SStefano Zampini for (k=j;k<subset_size;k++) { 7451cf9b237SStefano Zampini S [k*subset_size+j] = S [j*subset_size+k]; 7461cf9b237SStefano Zampini St[k*subset_size+j] = St[j*subset_size+k]; 7471cf9b237SStefano Zampini } 7481cf9b237SStefano Zampini } 7491cf9b237SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,S,&SM);CHKERRQ(ierr); 7501cf9b237SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,St,&StM);CHKERRQ(ierr); 7511cf9b237SStefano Zampini ierr = MatDetectDisconnectedComponents(SM,PETSC_TRUE,&nccs,NULL);CHKERRQ(ierr); 7521cf9b237SStefano Zampini ierr = MatDetectDisconnectedComponents(StM,PETSC_TRUE,&nccst,NULL);CHKERRQ(ierr); 7531cf9b237SStefano Zampini if (nccs != 1 || nccst != 1) { 7541cf9b237SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] Found disc %d %d (size %d)\n",PetscGlobalRank,nccs,nccst,subset_size); 7551cf9b237SStefano Zampini } 7561cf9b237SStefano Zampini ierr = MatDestroy(&SM);CHKERRQ(ierr); 7571cf9b237SStefano Zampini ierr = MatDestroy(&StM);CHKERRQ(ierr); 7581cf9b237SStefano Zampini } 759f6f667cfSStefano Zampini 7609ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 76108122e43SStefano Zampini PetscBLASInt B_itype = 1; 762f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 7634c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 7649552c7c7SStefano Zampini PetscInt nmin_s; 76508122e43SStefano Zampini 766fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 7678bec7fa6SStefano 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]]); 768fd14bc51SStefano Zampini } 769d16cbb6bSStefano Zampini 77008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 771d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 772d16cbb6bSStefano Zampini 773d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 77408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 775f6f667cfSStefano 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)); 77608122e43SStefano Zampini #else 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,B_iwork,B_ifail,&B_ierr)); 77808122e43SStefano Zampini #endif 779d16cbb6bSStefano Zampini } else { 780d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 781d16cbb6bSStefano Zampini B_IL = 1; 782d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 783d16cbb6bSStefano 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)); 784d16cbb6bSStefano Zampini #else 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,B_iwork,B_ifail,&B_ierr)); 786d16cbb6bSStefano Zampini #endif 787d16cbb6bSStefano Zampini } 78808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 78908122e43SStefano Zampini if (B_ierr) { 79008122e43SStefano Zampini if (B_ierr < 0 ) { 79108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 79208122e43SStefano Zampini } else if (B_ierr <= B_N) { 79308122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 79408122e43SStefano Zampini } else { 7959552c7c7SStefano 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); 79608122e43SStefano Zampini } 79708122e43SStefano Zampini } 79808122e43SStefano Zampini 79908122e43SStefano Zampini if (B_neigs > nmax) { 800fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 801fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 802fd14bc51SStefano Zampini } 803f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 80408122e43SStefano Zampini B_neigs = nmax; 80508122e43SStefano Zampini } 80608122e43SStefano Zampini 8079552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 8089552c7c7SStefano Zampini if (B_neigs < nmin_s) { 80908122e43SStefano Zampini PetscBLASInt B_neigs2; 81008122e43SStefano Zampini 811f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 812f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 813fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 814fd14bc51SStefano 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); 815fd14bc51SStefano Zampini } 8169ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 81708122e43SStefano Zampini PetscInt j; 81808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 81908122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 82008122e43SStefano Zampini } 82108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 82208122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 82308122e43SStefano Zampini } 82408122e43SStefano Zampini } else { 82508122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 82608122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 82708122e43SStefano Zampini } 82808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 82908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 830f6f667cfSStefano 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)); 83108122e43SStefano Zampini #else 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,B_iwork,B_ifail,&B_ierr)); 83308122e43SStefano Zampini #endif 83408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 83508122e43SStefano Zampini B_neigs += B_neigs2; 83608122e43SStefano Zampini } 83708122e43SStefano Zampini if (B_ierr) { 83808122e43SStefano Zampini if (B_ierr < 0 ) { 83908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 84008122e43SStefano Zampini } else if (B_ierr <= B_N) { 84108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 84208122e43SStefano Zampini } else { 8439552c7c7SStefano 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); 84408122e43SStefano Zampini } 84508122e43SStefano Zampini } 846fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 847ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 84808122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 84908122e43SStefano Zampini if (eigs[j] == 0.0) { 850ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 85108122e43SStefano Zampini } else { 852ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 853fd14bc51SStefano Zampini } 85408122e43SStefano Zampini } 85508122e43SStefano Zampini } 85608122e43SStefano Zampini } else { 85708122e43SStefano Zampini /* TODO */ 85808122e43SStefano Zampini } 859aff50787SStefano Zampini } 8608bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 8618bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 8629162d606SStefano Zampini if (B_neigs) { 8639162d606SStefano 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); 864fd14bc51SStefano Zampini 865fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 8669552c7c7SStefano Zampini PetscInt ii; 8679552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 868ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 8699552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 870ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 871ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 872ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 873ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 874ac47001eSStefano Zampini #else 875ac47001eSStefano 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); 876ac47001eSStefano Zampini #endif 8779552c7c7SStefano Zampini } 8789552c7c7SStefano Zampini } 879fd14bc51SStefano Zampini } 88008122e43SStefano Zampini #if 0 8819162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 88208122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 88308122e43SStefano Zampini PetscScalar norm; 88408122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 8859162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 8869162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 88708122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 88808122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 88908122e43SStefano Zampini } else { 89008122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 89108122e43SStefano Zampini } 8929162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 893b1b3d7a2SStefano Zampini } 894b1b3d7a2SStefano Zampini #endif 8959162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 8969162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 8979162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 8989162d606SStefano Zampini cum++; 89908122e43SStefano Zampini } 90008122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 90108122e43SStefano Zampini /* shift for next computation */ 90208122e43SStefano Zampini cumarray += subset_size*subset_size; 90308122e43SStefano Zampini } 904fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 905fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 906fd14bc51SStefano Zampini } 90708122e43SStefano Zampini 90808122e43SStefano Zampini if (mss) { 90908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 91008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 911f6f667cfSStefano Zampini /* destroy matrices (junk) */ 912f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 913f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 91408122e43SStefano Zampini } 915f6f667cfSStefano Zampini if (allocated_S_St) { 916f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 917f6f667cfSStefano Zampini } 918f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 91908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 92008122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 92108122e43SStefano Zampini #endif 92208122e43SStefano Zampini if (pcbddc->dbg_flag) { 9231b968477SStefano Zampini PetscInt maxneigs_r; 92408122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 9259b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 92608122e43SStefano Zampini } 92708122e43SStefano Zampini PetscFunctionReturn(0); 92808122e43SStefano Zampini } 929b1b3d7a2SStefano Zampini 930674ae819SStefano Zampini #undef __FUNCT__ 931c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 932c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 933c8587f34SStefano Zampini { 934c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 9358629588bSStefano Zampini PetscScalar *coarse_submat_vals; 936c8587f34SStefano Zampini PetscErrorCode ierr; 937c8587f34SStefano Zampini 938c8587f34SStefano Zampini PetscFunctionBegin; 939f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 9405e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 941c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 942c8587f34SStefano Zampini 943684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 9440fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 945684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 946c8587f34SStefano Zampini 947c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 948b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 949c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 950c8587f34SStefano Zampini } 951c8587f34SStefano Zampini 9528629588bSStefano Zampini /* 9538629588bSStefano Zampini Setup local correction and local part of coarse basis. 9548629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 9558629588bSStefano Zampini */ 95647f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 9578629588bSStefano Zampini 9588629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 9598629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 9608629588bSStefano Zampini 9618629588bSStefano Zampini /* free */ 9628629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 963c8587f34SStefano Zampini PetscFunctionReturn(0); 964c8587f34SStefano Zampini } 965c8587f34SStefano Zampini 966c8587f34SStefano Zampini #undef __FUNCT__ 967674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 968674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 969674ae819SStefano Zampini { 970674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 971674ae819SStefano Zampini PetscErrorCode ierr; 972674ae819SStefano Zampini 973674ae819SStefano Zampini PetscFunctionBegin; 974674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 975674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 97630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 977674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 978674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 979785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 980674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 981f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 982f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 983785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 98463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 98563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 986674ae819SStefano Zampini PetscFunctionReturn(0); 987674ae819SStefano Zampini } 988674ae819SStefano Zampini 989674ae819SStefano Zampini #undef __FUNCT__ 990674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 991674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 992674ae819SStefano Zampini { 993674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9944f1b2e48SStefano Zampini PetscInt i; 995674ae819SStefano Zampini PetscErrorCode ierr; 996674ae819SStefano Zampini 997674ae819SStefano Zampini PetscFunctionBegin; 998b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 999674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 1000674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1001674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 10024f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 10034f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 10044f1b2e48SStefano Zampini } 10054f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1006b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1007674ae819SStefano Zampini PetscFunctionReturn(0); 1008674ae819SStefano Zampini } 1009674ae819SStefano Zampini 1010674ae819SStefano Zampini #undef __FUNCT__ 1011674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1012674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1013674ae819SStefano Zampini { 1014674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 101506656605SStefano Zampini PetscScalar *array; 1016674ae819SStefano Zampini PetscErrorCode ierr; 1017674ae819SStefano Zampini 1018674ae819SStefano Zampini PetscFunctionBegin; 1019674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 102058da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 102106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 102206656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 102358da7f69SStefano Zampini } 1024674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1025674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 102615aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 102715aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1028674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1029674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1030674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 103106656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1032674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1033674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10348ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1035674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1036674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1037674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1038f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1039f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1040f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1041f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1042727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 10430e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1044f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 104570cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 10466e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 104781d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 10480369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 10498b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10504f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10514f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 10528b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 10534f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1054674ae819SStefano Zampini PetscFunctionReturn(0); 1055674ae819SStefano Zampini } 1056674ae819SStefano Zampini 1057674ae819SStefano Zampini #undef __FUNCT__ 1058f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1059f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 10606bfb1811SStefano Zampini { 10616bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10626bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 10636bfb1811SStefano Zampini VecType impVecType; 10644f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 10656bfb1811SStefano Zampini PetscErrorCode ierr; 10666bfb1811SStefano Zampini 10676bfb1811SStefano Zampini PetscFunctionBegin; 1068f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 1069019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1070f4ddd8eeSStefano Zampini } 1071e7b262bdSStefano Zampini /* get sizes */ 10724f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1073b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 10746bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1075e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1076e7b262bdSStefano Zampini /* R nodes */ 1077e7b262bdSStefano Zampini old_size = -1; 1078e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1079e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1080e7b262bdSStefano Zampini } 1081e7b262bdSStefano Zampini if (n_R != old_size) { 1082e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1083e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10846bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 10856bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 10866bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 10876bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1088e7b262bdSStefano Zampini } 1089e7b262bdSStefano Zampini /* local primal dofs */ 1090e7b262bdSStefano Zampini old_size = -1; 1091e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1092e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1093e7b262bdSStefano Zampini } 1094e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1095e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 109683b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1097e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 10986bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1099e7b262bdSStefano Zampini } 1100e7b262bdSStefano Zampini /* local explicit constraints */ 1101e7b262bdSStefano Zampini old_size = -1; 1102e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1103e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1104e7b262bdSStefano Zampini } 1105e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1106e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 110783b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 110883b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 110983b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 111083b7ccabSStefano Zampini } 11116bfb1811SStefano Zampini PetscFunctionReturn(0); 11126bfb1811SStefano Zampini } 11136bfb1811SStefano Zampini 11146bfb1811SStefano Zampini #undef __FUNCT__ 111547f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 111647f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 111788ebb749SStefano Zampini { 111825084f0cSStefano Zampini PetscErrorCode ierr; 111925084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 112088ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 112188ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1122d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 112325084f0cSStefano Zampini /* submatrices of local problem */ 112480677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 1125019a44ceSStefano Zampini /* submatrices of benign trick */ 1126d16cbb6bSStefano Zampini Mat B0_V = NULL; 112706656605SStefano Zampini /* submatrices of local coarse problem */ 112806656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 112925084f0cSStefano Zampini /* working matrices */ 113006656605SStefano Zampini Mat C_CR; 113125084f0cSStefano Zampini /* additional working stuff */ 113206656605SStefano Zampini PC pc_R; 11334f1b2e48SStefano Zampini Mat F; 113406656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 113506656605SStefano Zampini 113625084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 113706656605SStefano Zampini PetscScalar *work; 113806656605SStefano Zampini PetscInt *idx_V_B; 1139*ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 114006656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1141*ffd830a3SStefano Zampini 114225084f0cSStefano Zampini /* some shortcuts to scalars */ 114306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 114488ebb749SStefano Zampini 114588ebb749SStefano Zampini PetscFunctionBegin; 1146*ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1147*ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1148*ffd830a3SStefano Zampini } 1149*ffd830a3SStefano Zampini 1150*ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1151b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 11524f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 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 /* vertices in boundary numbering */ 1158785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 11590e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 116088ebb749SStefano Zampini if (i != n_vertices) { 116122d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 116288ebb749SStefano Zampini } 116388ebb749SStefano Zampini 116406656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1165019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 116606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 116706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 116806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 116906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 117006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 117106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 117206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 117306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 117406656605SStefano Zampini 117506656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 117606656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 117706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 117806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 117906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1180*ffd830a3SStefano Zampini lda_rhs = n_R; 118106656605SStefano Zampini if (isLU || isILU || isCHOL) { 118206656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1183d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 1184d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1185d62866d3SStefano Zampini MatFactorType type; 1186d62866d3SStefano Zampini 11876816873aSStefano Zampini F = reuse_mumps->F; 11886816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1189d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1190*ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 119106656605SStefano Zampini } else { 119206656605SStefano Zampini F = NULL; 119306656605SStefano Zampini } 119406656605SStefano Zampini 1195*ffd830a3SStefano Zampini /* allocate workspace */ 1196*ffd830a3SStefano Zampini n = 0; 1197*ffd830a3SStefano Zampini if (n_constraints) { 1198*ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1199*ffd830a3SStefano Zampini } 1200*ffd830a3SStefano Zampini if (n_vertices) { 1201*ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1202*ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1203*ffd830a3SStefano Zampini } 1204*ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1205*ffd830a3SStefano Zampini 120688ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 120788ebb749SStefano Zampini if (n_constraints) { 120806656605SStefano Zampini Mat M1,M2,M3; 120980677318SStefano Zampini Mat auxmat; 121006656605SStefano Zampini IS is_aux; 121180677318SStefano Zampini PetscScalar *array,*array2; 121206656605SStefano Zampini 1213f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 121480677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 121588ebb749SStefano Zampini 121625084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 121725084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 12188ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 121980677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 122088ebb749SStefano Zampini 122180677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 122280677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1223*ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 122488ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 122506656605SStefano Zampini const PetscScalar *row_cmat_values; 122606656605SStefano Zampini const PetscInt *row_cmat_indices; 122706656605SStefano Zampini PetscInt size_of_constraint,j; 122888ebb749SStefano Zampini 122906656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 123006656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1231*ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 123206656605SStefano Zampini } 123306656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 123406656605SStefano Zampini } 1235*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 123606656605SStefano Zampini if (F) { 123706656605SStefano Zampini Mat B; 123806656605SStefano Zampini 1239*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 124080677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 124106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 124206656605SStefano Zampini } else { 124380677318SStefano Zampini PetscScalar *marr; 124480677318SStefano Zampini 124580677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 124606656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1247*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1248*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 124906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 125006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 125106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 125206656605SStefano Zampini } 125380677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 125406656605SStefano Zampini } 125580677318SStefano Zampini if (!pcbddc->switch_static) { 125680677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 125780677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 125880677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 125980677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1260*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 126180677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 126280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126480677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 126580677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 126680677318SStefano Zampini } 126780677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 126880677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 126980677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 127080677318SStefano Zampini } else { 1271*ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1272*ffd830a3SStefano Zampini IS dummy; 1273*ffd830a3SStefano Zampini 1274*ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 1275*ffd830a3SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,dummy,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1276*ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1277*ffd830a3SStefano Zampini } else { 127880677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 127980677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1280*ffd830a3SStefano Zampini } 128125084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 128280677318SStefano Zampini } 128380677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 128480677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 128580677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 128606656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 128706656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 128880677318SStefano Zampini if (isCHOL) { 128980677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 129080677318SStefano Zampini } else { 129125084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 129280677318SStefano Zampini } 129380677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 129406656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 129525084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 129625084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 129725084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 129880677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 129980677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 130080677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 130106656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 130206656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1303f4ddd8eeSStefano Zampini } 130488ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 13054f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1306d16cbb6bSStefano Zampini IS dummy; 1307d16cbb6bSStefano Zampini Mat B0_R; 1308d16cbb6bSStefano Zampini PetscReal norm; 1309d16cbb6bSStefano Zampini 13104f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13114f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1312d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1313d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1314d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1315d16cbb6bSStefano Zampini } 1316d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1317d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1318d16cbb6bSStefano Zampini } 1319d16cbb6bSStefano Zampini 132088ebb749SStefano Zampini if (n_vertices) { 132106656605SStefano Zampini IS is_aux; 13223a50541eSStefano Zampini 13236816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 13246816873aSStefano Zampini IS tis; 13256816873aSStefano Zampini 13266816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 13276816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 13286816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 13296816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 13306816873aSStefano Zampini } else { 13313a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 13326816873aSStefano Zampini } 13339577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 13349577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 133504708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 13364f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1337019a44ceSStefano Zampini IS dummy; 1338019a44ceSStefano Zampini 13394f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13404f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1341019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1342019a44ceSStefano Zampini } 134325084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 134488ebb749SStefano Zampini } 134588ebb749SStefano Zampini 134688ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1347f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 134806656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 134906656605SStefano Zampini if (pcbddc->coarse_phi_D) { 135006656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 135106656605SStefano Zampini } 1352f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 135306656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 135406656605SStefano Zampini PetscScalar *marray; 135506656605SStefano Zampini 135606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 135706656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1358f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1359f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1360f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1361f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1362f4ddd8eeSStefano Zampini } 1363f4ddd8eeSStefano Zampini } 136406656605SStefano Zampini 1365f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 136606656605SStefano Zampini PetscScalar *marray; 136788ebb749SStefano Zampini 136806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13698eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 137006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 137188ebb749SStefano Zampini } 13723301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 137306656605SStefano Zampini n *= 2; 137488ebb749SStefano Zampini } 137506656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 137606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 137706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13788eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 137906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 138006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 138188ebb749SStefano Zampini } 13823301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 138306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 13848eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 138506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 138606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 138788ebb749SStefano Zampini } 138888ebb749SStefano Zampini } else { 1389c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1390c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 13911b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1392c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1393c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1394c0553b1fSStefano Zampini } 139588ebb749SStefano Zampini } 139606656605SStefano Zampini } 1397019a44ceSStefano Zampini 139806656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 13994f1b2e48SStefano Zampini p0_lidx_I = NULL; 14004f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1401d12edf2fSStefano Zampini const PetscInt *idxs; 1402d12edf2fSStefano Zampini 1403d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 14044f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 14054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 14064f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 14074f1b2e48SStefano Zampini } 1408d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1409d12edf2fSStefano Zampini } 1410d16cbb6bSStefano Zampini 141106656605SStefano Zampini /* vertices */ 141206656605SStefano Zampini if (n_vertices) { 141316f15bc4SStefano Zampini 1414*ffd830a3SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 141504708bb6SStefano Zampini 141616f15bc4SStefano Zampini if (n_R) { 141706656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 141806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 141916f15bc4SStefano Zampini PetscScalar *x,*y; 142004708bb6SStefano Zampini PetscBool isseqaij; 142106656605SStefano Zampini 142221eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 1423*ffd830a3SStefano Zampini if (lda_rhs == n_R) { 1424*ffd830a3SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 1425*ffd830a3SStefano Zampini } else { 1426*ffd830a3SStefano Zampini Mat A_RVt; 1427*ffd830a3SStefano Zampini PetscScalar *array; 1428*ffd830a3SStefano Zampini 1429*ffd830a3SStefano Zampini /* TODO optimize */ 1430*ffd830a3SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INITIAL_MATRIX,&A_RVt);CHKERRQ(ierr); 1431*ffd830a3SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1432*ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 1433*ffd830a3SStefano Zampini ierr = MatDenseGetArray(A_RVt,&array);CHKERRQ(ierr); 1434*ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 1435*ffd830a3SStefano Zampini ierr = PetscMemcpy(work+(n_vertices+i)*lda_rhs,array+i*n_R,n_R*sizeof(PetscScalar));CHKERRQ(ierr); 1436*ffd830a3SStefano Zampini } 1437*ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(A_RVt,&array);CHKERRQ(ierr); 1438*ffd830a3SStefano Zampini ierr = MatDestroy(&A_RVt);CHKERRQ(ierr); 1439*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&A_RV);CHKERRQ(ierr); 1440*ffd830a3SStefano Zampini } 1441*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 14426816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 144306656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 144406656605SStefano Zampini } else { 144506656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 144606656605SStefano Zampini for (i=0;i<n_vertices;i++) { 1447*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 1448*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 144906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 145006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 145106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 145206656605SStefano Zampini } 145306656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 145406656605SStefano Zampini } 145580677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1456*ffd830a3SStefano Zampini /* S_VV and S_CV */ 145706656605SStefano Zampini if (n_constraints) { 145806656605SStefano Zampini Mat B; 145980677318SStefano Zampini 1460*ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 146180677318SStefano Zampini for (i=0;i<n_vertices;i++) { 1462*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1463*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 146480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 146580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 146680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 146780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 146880677318SStefano Zampini } 1469*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 147080677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 147180677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1472*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 147380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 147406656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 1475*ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 1476*ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 147706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 147806656605SStefano Zampini } 147904708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 148004708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 148104708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 148204708bb6SStefano Zampini } 1483*ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1484*ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 1485*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 1486*ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 1487*ffd830a3SStefano Zampini } 148806656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 148980677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 149006656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 149106656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 149206656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 149306656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 149406656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 149506656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 149606656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1497d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1498019a44ceSStefano Zampini } else { 1499d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1500d16cbb6bSStefano Zampini } 15014f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1502019a44ceSStefano Zampini const PetscScalar *vals; 1503019a44ceSStefano Zampini const PetscInt *idxs; 15044f1b2e48SStefano Zampini PetscInt n,j,primal_idx; 1505019a44ceSStefano Zampini 15064f1b2e48SStefano Zampini ierr = MatGetRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 15074f1b2e48SStefano Zampini primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + i; 1508d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 15094f1b2e48SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+idxs[j]] = vals[j]; 15104f1b2e48SStefano Zampini coarse_submat_vals[idxs[j]*pcbddc->local_primal_size+primal_idx] = vals[j]; 1511019a44ceSStefano Zampini } 15124f1b2e48SStefano Zampini ierr = MatRestoreRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 151316f15bc4SStefano Zampini } 151421eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1515d16cbb6bSStefano Zampini 151606656605SStefano Zampini /* coarse basis functions */ 151706656605SStefano Zampini for (i=0;i<n_vertices;i++) { 151816f15bc4SStefano Zampini PetscScalar *y; 151916f15bc4SStefano Zampini 1520*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 152106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 152206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 152306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 152406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 152506656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 152606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 152706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 152806656605SStefano Zampini 152906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15304f1b2e48SStefano Zampini PetscInt j; 15314f1b2e48SStefano Zampini 153206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 153306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 153406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 153506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 153606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15374f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 153806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 153906656605SStefano Zampini } 154006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 154106656605SStefano Zampini } 154204708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 154304708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 154406656605SStefano Zampini } 154506656605SStefano Zampini 154606656605SStefano Zampini if (n_constraints) { 154706656605SStefano Zampini Mat B; 154806656605SStefano Zampini 1549*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 155006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 155180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 155206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 155306656605SStefano Zampini if (n_vertices) { 155480677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 155580677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 155680677318SStefano Zampini } else { 155780677318SStefano Zampini Mat S_VCt; 155880677318SStefano Zampini 1559*ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1560*ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1561*ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B);CHKERRQ(ierr); 1562*ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 1563*ffd830a3SStefano Zampini } 156480677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 156580677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 156680677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 156780677318SStefano Zampini } 156806656605SStefano Zampini } 156906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 157006656605SStefano Zampini /* coarse basis functions */ 157106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 157206656605SStefano Zampini PetscScalar *y; 157306656605SStefano Zampini 1574*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 157506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 157606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 157706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 157806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 157906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 158006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 158106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15824f1b2e48SStefano Zampini PetscInt j; 15834f1b2e48SStefano Zampini 158406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 158506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 158606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 158706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 158806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15894f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 159006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 159106656605SStefano Zampini } 159206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 159306656605SStefano Zampini } 159406656605SStefano Zampini } 159580677318SStefano Zampini if (n_constraints) { 159680677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 159780677318SStefano Zampini } 15984f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 1599019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1600019a44ceSStefano Zampini 160106656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 16023301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 1603*ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 1604*ffd830a3SStefano Zampini PetscScalar *marray; 160506656605SStefano Zampini 160606656605SStefano Zampini if (n_constraints) { 1607*ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 160806656605SStefano Zampini 1609*ffd830a3SStefano Zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 161006656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 1611*ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 161216f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 161306656605SStefano Zampini if (n_vertices) { 1614*ffd830a3SStefano Zampini Mat S_VCT; 161506656605SStefano Zampini 161606656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 1617*ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 161816f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 161906656605SStefano Zampini } 1620*ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 162106656605SStefano Zampini } 162216f15bc4SStefano Zampini if (n_vertices && n_R) { 1623*ffd830a3SStefano Zampini PetscScalar *av,*marray; 1624*ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 1625*ffd830a3SStefano Zampini PetscInt n; 1626*ffd830a3SStefano Zampini PetscBool flg_row; 162706656605SStefano Zampini 1628*ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 1629*ffd830a3SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 1630*ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1631*ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 1632*ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 1633*ffd830a3SStefano Zampini for (i=0;i<n;i++) { 1634*ffd830a3SStefano Zampini PetscInt j; 1635*ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 1636*ffd830a3SStefano Zampini } 1637*ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 1638*ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1639*ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 164006656605SStefano Zampini } 164106656605SStefano Zampini 1642*ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 1643*ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 1644*ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 1645*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 1646*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 164706656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 164806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 164906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 165006656605SStefano Zampini } 1651*ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 1652*ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 1653*ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 1654*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 1655*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 1656*ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1657*ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1658*ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 165906656605SStefano Zampini } 1660*ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 166106656605SStefano Zampini /* coarse basis functions */ 166206656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 166306656605SStefano Zampini PetscScalar *y; 166406656605SStefano Zampini 1665*ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 166606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 166706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 166806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 166906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 167006656605SStefano Zampini if (i<n_vertices) { 167106656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 167206656605SStefano Zampini } 167306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 167406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 167506656605SStefano Zampini 167606656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 167706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 167806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 167906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 168006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 168106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 168206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 168306656605SStefano Zampini } 168406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 168506656605SStefano Zampini } 1686*ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 1687*ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 168806656605SStefano Zampini } 1689d62866d3SStefano Zampini /* free memory */ 169088ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 169106656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 169206656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 169306656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 169406656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 1695d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1696d62866d3SStefano Zampini if (n_vertices) { 1697d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1698d62866d3SStefano Zampini } 1699d62866d3SStefano Zampini if (n_constraints) { 1700d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 1701d62866d3SStefano Zampini } 170288ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 170388ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 170488ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1705d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 170688ebb749SStefano Zampini Mat coarse_sub_mat; 170725084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 170888ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 170988ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 171088ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 17118bec7fa6SStefano Zampini Mat C_B,CPHI; 17128bec7fa6SStefano Zampini IS is_dummy; 17138bec7fa6SStefano Zampini Vec mones; 171488ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 171588ebb749SStefano Zampini PetscReal real_value; 171688ebb749SStefano Zampini 171788ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 171888ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 171988ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 172088ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 172188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 172288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1723*ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 172488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 172588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 172688ebb749SStefano Zampini } 172788ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 172888ebb749SStefano Zampini 172925084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 17303301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 173125084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1732*ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 173388ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 173488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 173588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 173688ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 173788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 173888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 173988ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 174088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 174188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 174288ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 174388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 174488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 174588ebb749SStefano Zampini } else { 174688ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 174788ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 174888ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 174988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 175088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 175188ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 175288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 175388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 175488ebb749SStefano Zampini } 175588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 175688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 175788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 175888ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 17594f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1760d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 1761d12edf2fSStefano Zampini PetscScalar *data,*data2; 17624f1b2e48SStefano Zampini PetscInt j; 1763d12edf2fSStefano Zampini 17644f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 17654f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 17664f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 1767d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 1768d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 1769d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 1770d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 17714f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 17724f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 1773d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 17744f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 17754f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 17764f1b2e48SStefano Zampini } 1777d12edf2fSStefano Zampini } 1778d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 1779d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 1780d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 1781d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 1782d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 1783d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 1784d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 1785d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1786d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 1787d12edf2fSStefano Zampini } 1788d12edf2fSStefano Zampini #if 0 1789d12edf2fSStefano Zampini { 1790d12edf2fSStefano Zampini PetscViewer viewer; 1791d12edf2fSStefano Zampini char filename[256]; 1792*ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 1793d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1794d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1795*ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 1796*ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 1797*ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 1798d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 1799*ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 1800*ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 1801*ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 1802*ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 1803*ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 1804*ffd830a3SStefano Zampini } 1805*ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 1806*ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 1807*ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 1808*ffd830a3SStefano Zampini } 1809*ffd830a3SStefano Zampini if (pcbddc->coarse_phi_B) { 1810*ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 1811*ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 1812*ffd830a3SStefano Zampini } 1813d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1814d12edf2fSStefano Zampini } 1815d12edf2fSStefano Zampini #endif 181681d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 18178bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 18180fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 181906656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 18208bec7fa6SStefano Zampini 18218bec7fa6SStefano Zampini /* check constraints */ 18224f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 18238bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 18248bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 18258bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 18268bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 18278bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 18288bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 18298bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1830bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 1831*ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 1832bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 1833bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 1834bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 1835bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1836bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 183788ebb749SStefano Zampini } 18388bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 18398bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 18408bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 18418bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 1842d12edf2fSStefano Zampini } 184325084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 184488ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 184588ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 184688ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 184788ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 184888ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 184988ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 185088ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 185188ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 185288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 185388ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 1854*ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 185588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 185688ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 185788ebb749SStefano Zampini } 185888ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 185988ebb749SStefano Zampini } 18608629588bSStefano Zampini /* get back data */ 18618629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 186288ebb749SStefano Zampini PetscFunctionReturn(0); 186388ebb749SStefano Zampini } 186488ebb749SStefano Zampini 186588ebb749SStefano Zampini #undef __FUNCT__ 1866d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1867d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 1868aa0d41d4SStefano Zampini { 1869d65f70fdSStefano Zampini Mat *work_mat; 1870d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1871d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1872d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1873aa0d41d4SStefano Zampini PetscErrorCode ierr; 1874aa0d41d4SStefano Zampini 1875aa0d41d4SStefano Zampini PetscFunctionBegin; 1876d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1877d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1878d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1879d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1880aa0d41d4SStefano Zampini 1881d65f70fdSStefano Zampini if (!rsorted) { 1882906d46d4SStefano Zampini const PetscInt *idxs; 1883906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 1884aa0d41d4SStefano Zampini 1885d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1886d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1887d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1888d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1889aa0d41d4SStefano Zampini } 1890d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1891d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1892d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1893d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1894aa0d41d4SStefano Zampini } 1895d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1896d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1897d65f70fdSStefano Zampini } else { 1898d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1899d65f70fdSStefano Zampini isrow_s = isrow; 1900aa0d41d4SStefano Zampini } 1901906d46d4SStefano Zampini 1902d65f70fdSStefano Zampini if (!csorted) { 1903d65f70fdSStefano Zampini if (isrow == iscol) { 1904d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1905d65f70fdSStefano Zampini iscol_s = isrow_s; 1906d65f70fdSStefano Zampini } else { 1907d65f70fdSStefano Zampini const PetscInt *idxs; 1908d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1909906d46d4SStefano Zampini 1910d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1911d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1912d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1913d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1914d65f70fdSStefano Zampini } 1915d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1916d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1917d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1918d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1919d65f70fdSStefano Zampini } 1920d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1921d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1922d65f70fdSStefano Zampini } 1923d65f70fdSStefano Zampini } else { 1924d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1925d65f70fdSStefano Zampini iscol_s = iscol; 1926d65f70fdSStefano Zampini } 1927d65f70fdSStefano Zampini 1928d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1929d65f70fdSStefano Zampini 1930d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1931906d46d4SStefano Zampini Mat new_mat; 1932d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1933906d46d4SStefano Zampini 1934d65f70fdSStefano Zampini if (!rsorted) { 1935d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1936d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1937d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1938d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1939906d46d4SStefano Zampini } 1940d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1941d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1942d65f70fdSStefano Zampini } else { 1943d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1944906d46d4SStefano Zampini } 1945d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1946d65f70fdSStefano Zampini 1947d65f70fdSStefano Zampini if (!csorted) { 1948d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1949d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1950d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1951d65f70fdSStefano Zampini } else { 1952d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1953d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1954d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1955d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1956d65f70fdSStefano Zampini } 1957d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1958d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1959d65f70fdSStefano Zampini } 1960d65f70fdSStefano Zampini } else { 1961d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1962d65f70fdSStefano Zampini } 1963d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1964d65f70fdSStefano Zampini 1965d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1966d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1967d65f70fdSStefano Zampini work_mat[0] = new_mat; 1968d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1969d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1970d65f70fdSStefano Zampini } 1971d65f70fdSStefano Zampini 1972d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1973d65f70fdSStefano Zampini *B = work_mat[0]; 1974d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1975d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1976d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1977d65f70fdSStefano Zampini PetscFunctionReturn(0); 1978d65f70fdSStefano Zampini } 1979d65f70fdSStefano Zampini 1980d65f70fdSStefano Zampini #undef __FUNCT__ 19815e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 19825e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1983aa0d41d4SStefano Zampini { 1984aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 19855e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1986d65f70fdSStefano Zampini Mat new_mat; 19875e8657edSStefano Zampini IS is_local,is_global; 1988d65f70fdSStefano Zampini PetscInt local_size; 1989d65f70fdSStefano Zampini PetscBool isseqaij; 1990aa0d41d4SStefano Zampini PetscErrorCode ierr; 1991aa0d41d4SStefano Zampini 1992aa0d41d4SStefano Zampini PetscFunctionBegin; 1993aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 19945e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 19955e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1996b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 1997aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1998d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 1999aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2000906d46d4SStefano Zampini 2001906d46d4SStefano Zampini /* check */ 2002906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2003906d46d4SStefano Zampini Vec x,x_change; 2004906d46d4SStefano Zampini PetscReal error; 2005906d46d4SStefano Zampini 20065e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2007906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 20085e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2009e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2010e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2011d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2012e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2013e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2014906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2015906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2016906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2017906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2018906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2019906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2020906d46d4SStefano Zampini } 2021906d46d4SStefano Zampini 202222d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 20239b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 202422d5777bSStefano Zampini if (isseqaij) { 20251cf9b237SStefano Zampini Mat M; 20261cf9b237SStefano Zampini 20271cf9b237SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 20281cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 20291cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2030aa0d41d4SStefano Zampini } else { 20311cf9b237SStefano Zampini Mat work_mat,M; 20321cf9b237SStefano Zampini 2033aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 20341cf9b237SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 20351cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 20361cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2037aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2038aa0d41d4SStefano Zampini } 20393301b35fSStefano Zampini if (matis->A->symmetric_set) { 20403301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2041e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 20423301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2043e496cd5dSStefano Zampini #endif 20443301b35fSStefano Zampini } 204545a1bb75SStefano Zampini /* 204645a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2047d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 204845a1bb75SStefano Zampini */ 2049d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2050aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2051aa0d41d4SStefano Zampini } 2052aa0d41d4SStefano Zampini 2053aa0d41d4SStefano Zampini #undef __FUNCT__ 2054a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 20558ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2056a64d13efSStefano Zampini { 2057a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2058a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2059d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 206053892102SStefano Zampini PetscInt *idx_R_local=NULL; 20613a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 20623a50541eSStefano Zampini PetscInt vbs,bs; 20636816873aSStefano Zampini PetscBT bitmask=NULL; 2064a64d13efSStefano Zampini PetscErrorCode ierr; 2065a64d13efSStefano Zampini 2066a64d13efSStefano Zampini PetscFunctionBegin; 2067b23d619eSStefano Zampini /* 2068b23d619eSStefano Zampini No need to setup local scatters if 2069b23d619eSStefano Zampini - primal space is unchanged 2070b23d619eSStefano Zampini AND 2071b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2072b23d619eSStefano Zampini AND 2073b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2074b23d619eSStefano Zampini */ 2075b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2076f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2077f4ddd8eeSStefano Zampini } 2078f4ddd8eeSStefano Zampini /* destroy old objects */ 2079f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2080f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2081f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2082a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2083b371cd4fSStefano Zampini n_B = pcis->n_B; 2084b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2085b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 20863a50541eSStefano Zampini 2087a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 20886816873aSStefano Zampini 208953892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 20906816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 2091854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2092a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2093a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 20940e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2095a64d13efSStefano Zampini } 2096a64d13efSStefano Zampini 2097a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 20984641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 20996816873aSStefano Zampini idx_R_local[n_R++] = i; 2100a64d13efSStefano Zampini } 2101a64d13efSStefano Zampini } 210253892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 21036816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 21046816873aSStefano Zampini 210553892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 210653892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 21076816873aSStefano Zampini } 21083a50541eSStefano Zampini 21093a50541eSStefano Zampini /* Block code */ 21103a50541eSStefano Zampini vbs = 1; 21113a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 21123a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 21133a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 21143a50541eSStefano Zampini PetscInt *vary; 2115d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 2116785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 21173a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2118d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2119d3df7717SStefano 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 */ 21200e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2121d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 21223a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 21233a50541eSStefano Zampini is_blocked = PETSC_FALSE; 21243a50541eSStefano Zampini break; 21253a50541eSStefano Zampini } 21263a50541eSStefano Zampini } 2127d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2128d3df7717SStefano Zampini } else { 2129d3df7717SStefano Zampini /* Verify directly the R set */ 2130d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2131d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2132d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2133d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2134d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2135d3df7717SStefano Zampini break; 2136d3df7717SStefano Zampini } 2137d3df7717SStefano Zampini } 2138d3df7717SStefano Zampini } 2139d3df7717SStefano Zampini } 21403a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 21413a50541eSStefano Zampini vbs = bs; 21423a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 21433a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 21443a50541eSStefano Zampini } 21453a50541eSStefano Zampini } 21463a50541eSStefano Zampini } 21473a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 214853892102SStefano Zampini if (sub_schurs->reuse_mumps) { 214953892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 215053892102SStefano Zampini 215153892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 215253892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 215353892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 215453892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 215553892102SStefano Zampini } else { 21563a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 215753892102SStefano Zampini } 2158a64d13efSStefano Zampini 2159a64d13efSStefano Zampini /* print some info if requested */ 2160a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2161a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2162a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 21630fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2164a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2165a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 21664f1b2e48SStefano 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); 2167a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2168a64d13efSStefano Zampini } 2169a64d13efSStefano Zampini 2170a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 21716816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 21726816873aSStefano Zampini IS is_aux1,is_aux2; 21736816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 21746816873aSStefano Zampini 21753a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2176854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2177854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2178a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 21794641a718SStefano Zampini for (i=0; i<n_D; i++) { 21804641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 21814641a718SStefano Zampini } 2182a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2183a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 21844641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 21854641a718SStefano Zampini aux_array1[j++] = i; 2186a64d13efSStefano Zampini } 2187a64d13efSStefano Zampini } 2188a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2189a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2190a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 21914641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 21924641a718SStefano Zampini aux_array2[j++] = i; 2193a64d13efSStefano Zampini } 2194a64d13efSStefano Zampini } 2195a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2196a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2197a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2198a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2199a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2200a64d13efSStefano Zampini 22018eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2202785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2203a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 22044641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 22054641a718SStefano Zampini aux_array1[j++] = i; 2206a64d13efSStefano Zampini } 2207a64d13efSStefano Zampini } 2208a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2209a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2210a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2211a64d13efSStefano Zampini } 22124641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 22133a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2214d62866d3SStefano Zampini } else { 221553892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 22166816873aSStefano Zampini IS tis; 22176816873aSStefano Zampini PetscInt schur_size; 22186816873aSStefano Zampini 221953892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 22206816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 222153892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 22226816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 22236816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 22246816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 22256816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 22266816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2227d62866d3SStefano Zampini } 2228d62866d3SStefano Zampini } 2229a64d13efSStefano Zampini PetscFunctionReturn(0); 2230a64d13efSStefano Zampini } 2231a64d13efSStefano Zampini 2232304d26faSStefano Zampini 2233304d26faSStefano Zampini #undef __FUNCT__ 2234304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2235684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2236304d26faSStefano Zampini { 2237304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2238304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2239304d26faSStefano Zampini PC pc_temp; 2240304d26faSStefano Zampini Mat A_RR; 2241f4ddd8eeSStefano Zampini MatReuse reuse; 2242304d26faSStefano Zampini PetscScalar m_one = -1.0; 2243304d26faSStefano Zampini PetscReal value; 224404708bb6SStefano Zampini PetscInt n_D,n_R; 22459577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2246304d26faSStefano Zampini PetscErrorCode ierr; 2247e604994aSStefano Zampini /* prefixes stuff */ 2248312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2249e604994aSStefano Zampini size_t len; 2250304d26faSStefano Zampini 2251304d26faSStefano Zampini PetscFunctionBegin; 2252304d26faSStefano Zampini 2253e604994aSStefano Zampini /* compute prefixes */ 2254e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2255e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2256e604994aSStefano Zampini if (!pcbddc->current_level) { 2257e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2258e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2259e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2260e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2261e604994aSStefano Zampini } else { 2262e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2263312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2264e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2265e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2266312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2267312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 226834d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 226934d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2270e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2271e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2272e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2273e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2274e604994aSStefano Zampini } 2275e604994aSStefano Zampini 2276304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2277684f6988SStefano Zampini if (dirichlet) { 2278d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 22793301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 22803301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2281964fefecSStefano Zampini } 2282ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2283964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2284304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2285304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2286304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2287304d26faSStefano Zampini /* default */ 2288304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2289e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 22909577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2291304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 22929577ea80SStefano Zampini if (issbaij) { 22939577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 22949577ea80SStefano Zampini } else { 2295304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 22969577ea80SStefano Zampini } 2297304d26faSStefano Zampini /* Allow user's customization */ 2298304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2299304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2300304d26faSStefano Zampini } 2301d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 2302d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2303d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2304d62866d3SStefano Zampini 2305d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 2306d5574798SStefano Zampini } 2307304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2308304d26faSStefano Zampini if (!n_D) { 2309304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 2310304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2311304d26faSStefano Zampini } 2312304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 2313304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 2314304d26faSStefano Zampini /* set ksp_D into pcis data */ 2315304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 2316304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 2317304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 2318684f6988SStefano Zampini } 2319304d26faSStefano Zampini 2320304d26faSStefano Zampini /* NEUMANN PROBLEM */ 2321684f6988SStefano Zampini A_RR = 0; 2322684f6988SStefano Zampini if (neumann) { 2323d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 232404708bb6SStefano Zampini PetscInt ibs,mbs; 232504708bb6SStefano Zampini PetscBool issbaij; 232604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2327f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 23288ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 2329f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 2330f4ddd8eeSStefano Zampini PetscInt nn_R; 233181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 2332f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2333f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 2334f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 2335f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 2336f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2337f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2338f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 2339727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 2340f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2341f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2342f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 2343f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 2344f4ddd8eeSStefano Zampini } 2345f4ddd8eeSStefano Zampini } 2346f4ddd8eeSStefano Zampini /* last check */ 2347d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 2348f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2349f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2350f4ddd8eeSStefano Zampini } 2351f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 2352f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2353f4ddd8eeSStefano Zampini } 2354f4ddd8eeSStefano Zampini /* extract A_RR */ 2355af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 2356af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 235704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 235804708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 235904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 236004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 236104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2362af732b37SStefano Zampini } else { 236304708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 23646816873aSStefano Zampini } 236504708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 236604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 236704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 236804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 236904708bb6SStefano Zampini } else { 237004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 237104708bb6SStefano Zampini } 237204708bb6SStefano Zampini } 2373f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 23743301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 23753301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 23766816873aSStefano Zampini } 2377f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2378304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2379304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2380304d26faSStefano Zampini /* default */ 2381304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2382e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2383304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 23849577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 23859577ea80SStefano Zampini if (issbaij) { 23869577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 23879577ea80SStefano Zampini } else { 2388304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 23899577ea80SStefano Zampini } 2390304d26faSStefano Zampini /* Allow user's customization */ 2391304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2392304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2393304d26faSStefano Zampini } 2394304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2395304d26faSStefano Zampini if (!n_R) { 2396304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2397304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2398304d26faSStefano Zampini } 2399d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 2400d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2401d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2402d62866d3SStefano Zampini 2403d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 2404d62866d3SStefano Zampini } 2405*ffd830a3SStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2406304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2407304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2408684f6988SStefano Zampini } 24096816873aSStefano Zampini /* free Neumann problem's matrix */ 24106816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2411304d26faSStefano Zampini 2412304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 24130fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2414684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2415684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2416684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2417684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2418684f6988SStefano Zampini } 2419684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 24200fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 24210fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 24220fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 24230fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 24240fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2425304d26faSStefano Zampini /* need to be adapted? */ 2426b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2427b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2428b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2429304d26faSStefano Zampini /* print info */ 2430304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2431e604994aSStefano 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); 2432304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2433304d26faSStefano Zampini } 2434b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2435298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2436304d26faSStefano Zampini } 2437684f6988SStefano Zampini } 2438684f6988SStefano Zampini if (neumann) { /* Neumann */ 24396816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 24400fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 24410fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 24420fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 24430fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 24440fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2445304d26faSStefano Zampini /* need to be adapted? */ 2446b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2447b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2448304d26faSStefano Zampini /* print info */ 2449304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2450e604994aSStefano 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); 2451304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2452304d26faSStefano Zampini } 2453b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2454298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2455304d26faSStefano Zampini } 24560fccc4e9SStefano Zampini } 2457684f6988SStefano Zampini } 2458304d26faSStefano Zampini PetscFunctionReturn(0); 2459304d26faSStefano Zampini } 2460304d26faSStefano Zampini 2461304d26faSStefano Zampini #undef __FUNCT__ 2462ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 246380677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2464674ae819SStefano Zampini { 2465674ae819SStefano Zampini PetscErrorCode ierr; 2466674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2467be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2468674ae819SStefano Zampini 2469674ae819SStefano Zampini PetscFunctionBegin; 2470be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 247180677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 247220c7b377SStefano Zampini } 247380677318SStefano Zampini if (!pcbddc->switch_static) { 247480677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 247580677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 247680677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 247720c7b377SStefano Zampini } 2478be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 247980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 248080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 248120c7b377SStefano Zampini } else { 2482be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2483be83ff47SStefano Zampini 248453892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248553892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248620c7b377SStefano Zampini } 2487be83ff47SStefano Zampini } else { 248880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 248980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 249080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 249180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 249280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 249380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 249480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 249580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 249680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2497674ae819SStefano Zampini } 2498674ae819SStefano Zampini } 2499be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 250080677318SStefano Zampini if (applytranspose) { 250180677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 250280677318SStefano Zampini } else { 250380677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 250480677318SStefano Zampini } 250553892102SStefano Zampini #if defined(PETSC_HAVE_MUMPS) 2506be83ff47SStefano Zampini } else { 2507be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2508be83ff47SStefano Zampini 2509be83ff47SStefano Zampini if (applytranspose) { 251053892102SStefano Zampini ierr = MatMumpsSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2511be83ff47SStefano Zampini } else { 251253892102SStefano Zampini ierr = MatMumpsSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2513be83ff47SStefano Zampini } 251453892102SStefano Zampini #endif 2515be83ff47SStefano Zampini } 251680677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 251780677318SStefano Zampini if (!pcbddc->switch_static) { 2518be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 251980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 252080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2521be83ff47SStefano Zampini } else { 2522be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2523be83ff47SStefano Zampini 252453892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 252553892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2526be83ff47SStefano Zampini } 252780677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 252880677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 252980677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 253080677318SStefano Zampini } 253180677318SStefano Zampini } else { 253280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253680677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 253780677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 253880677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 253980677318SStefano Zampini } 254080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 254180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 254280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 254380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2544674ae819SStefano Zampini } 2545674ae819SStefano Zampini PetscFunctionReturn(0); 2546674ae819SStefano Zampini } 2547674ae819SStefano Zampini 2548dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2549674ae819SStefano Zampini #undef __FUNCT__ 2550674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2551dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2552674ae819SStefano Zampini { 2553674ae819SStefano Zampini PetscErrorCode ierr; 2554674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2555674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2556674ae819SStefano Zampini const PetscScalar zero = 0.0; 2557674ae819SStefano Zampini 2558674ae819SStefano Zampini PetscFunctionBegin; 2559dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2560dc359a40SStefano Zampini if (applytranspose) { 2561674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 25628eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2563dc359a40SStefano Zampini } else { 2564674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2565674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 256615aaf578SStefano Zampini } 2567efc2fbd9SStefano Zampini 2568efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 25694f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2570efc2fbd9SStefano Zampini PetscScalar *array; 25714f1b2e48SStefano Zampini PetscInt j; 2572efc2fbd9SStefano Zampini 2573efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 25744f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 2575efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2576efc2fbd9SStefano Zampini } 2577efc2fbd9SStefano Zampini 257812edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 257912edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 258012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 258112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 258212edc857SStefano Zampini 25839f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 258412edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 258512edc857SStefano Zampini if (pcbddc->coarse_ksp) { 258651694757SStefano Zampini Mat coarse_mat; 2587964fefecSStefano Zampini Vec rhs,sol; 258851694757SStefano Zampini MatNullSpace nullsp; 2589964fefecSStefano Zampini 2590964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2591964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 259251694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 259351694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 259451694757SStefano Zampini if (nullsp) { 259551694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 259651694757SStefano Zampini } 259712edc857SStefano Zampini if (applytranspose) { 2598964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 259912edc857SStefano Zampini } else { 2600964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 260112edc857SStefano Zampini } 260251694757SStefano Zampini if (nullsp) { 260351694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 260451694757SStefano Zampini } 260512edc857SStefano Zampini } 2606674ae819SStefano Zampini 2607674ae819SStefano Zampini /* Local solution on R nodes */ 260880677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 260980677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 26109f00e9b4SStefano Zampini } 2611674ae819SStefano Zampini 26129f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 26139f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 261412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2615674ae819SStefano Zampini 2616674ae819SStefano Zampini /* Sum contributions from two levels */ 2617dc359a40SStefano Zampini if (applytranspose) { 2618dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2619dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2620dc359a40SStefano Zampini } else { 2621674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 26228eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2623dc359a40SStefano Zampini } 2624efc2fbd9SStefano Zampini /* store p0 */ 26254f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2626efc2fbd9SStefano Zampini PetscScalar *array; 26274f1b2e48SStefano Zampini PetscInt j; 2628efc2fbd9SStefano Zampini 2629efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 26304f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 2631efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2632efc2fbd9SStefano Zampini } 2633674ae819SStefano Zampini PetscFunctionReturn(0); 2634674ae819SStefano Zampini } 2635674ae819SStefano Zampini 2636674ae819SStefano Zampini #undef __FUNCT__ 2637674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 263812edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2639674ae819SStefano Zampini { 2640674ae819SStefano Zampini PetscErrorCode ierr; 2641674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 264258da7f69SStefano Zampini PetscScalar *array; 264312edc857SStefano Zampini Vec from,to; 2644674ae819SStefano Zampini 2645674ae819SStefano Zampini PetscFunctionBegin; 264612edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 264712edc857SStefano Zampini from = pcbddc->coarse_vec; 264812edc857SStefano Zampini to = pcbddc->vec1_P; 264912edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 265012edc857SStefano Zampini Vec tvec; 265158da7f69SStefano Zampini 265258da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 265358da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 265412edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 265558da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 265658da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 265758da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 265812edc857SStefano Zampini } 265912edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 266012edc857SStefano Zampini from = pcbddc->vec1_P; 266112edc857SStefano Zampini to = pcbddc->coarse_vec; 266212edc857SStefano Zampini } 266312edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 2664674ae819SStefano Zampini PetscFunctionReturn(0); 2665674ae819SStefano Zampini } 2666674ae819SStefano Zampini 2667674ae819SStefano Zampini #undef __FUNCT__ 2668674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 266912edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 2670674ae819SStefano Zampini { 2671674ae819SStefano Zampini PetscErrorCode ierr; 2672674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 267358da7f69SStefano Zampini PetscScalar *array; 267412edc857SStefano Zampini Vec from,to; 2675674ae819SStefano Zampini 2676674ae819SStefano Zampini PetscFunctionBegin; 267712edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 267812edc857SStefano Zampini from = pcbddc->coarse_vec; 267912edc857SStefano Zampini to = pcbddc->vec1_P; 268012edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 268112edc857SStefano Zampini from = pcbddc->vec1_P; 268212edc857SStefano Zampini to = pcbddc->coarse_vec; 268312edc857SStefano Zampini } 268412edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 268512edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 268612edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 268712edc857SStefano Zampini Vec tvec; 268858da7f69SStefano Zampini 268912edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 269058da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 269158da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 269258da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 269358da7f69SStefano Zampini } 269458da7f69SStefano Zampini } else { 269558da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 269658da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 269712edc857SStefano Zampini } 269812edc857SStefano Zampini } 2699674ae819SStefano Zampini PetscFunctionReturn(0); 2700674ae819SStefano Zampini } 2701674ae819SStefano Zampini 2702984c4197SStefano Zampini /* uncomment for testing purposes */ 2703984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 2704674ae819SStefano Zampini #undef __FUNCT__ 2705674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 2706674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 2707674ae819SStefano Zampini { 2708674ae819SStefano Zampini PetscErrorCode ierr; 2709674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2710674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2711674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2712984c4197SStefano Zampini /* one and zero */ 2713984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 2714984c4197SStefano Zampini /* space to store constraints and their local indices */ 27159162d606SStefano Zampini PetscScalar *constraints_data; 27169162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 27179162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 27189162d606SStefano Zampini PetscInt *constraints_n; 2719984c4197SStefano Zampini /* iterators */ 2720b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 2721984c4197SStefano Zampini /* BLAS integers */ 2722e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2723e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2724c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2725727cdba6SStefano Zampini /* reuse */ 27260e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 27270e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2728984c4197SStefano Zampini /* change of basis */ 2729b3d85658SStefano Zampini PetscBool qr_needed; 27309162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2731984c4197SStefano Zampini /* auxiliary stuff */ 273264efe560SStefano Zampini PetscInt *nnz,*is_indices; 27338a0068c3SStefano Zampini PetscInt ncc; 2734984c4197SStefano Zampini /* some quantities */ 273545a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2736a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2737984c4197SStefano Zampini 2738674ae819SStefano Zampini PetscFunctionBegin; 27398e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 27408e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 27418e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2742088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2743088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 27440e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 27450e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 27460e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 27470e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 27480e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2749088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2750cf5a6209SStefano Zampini 2751cf5a6209SStefano Zampini /* print some info */ 2752cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2753cf5a6209SStefano Zampini IS vertices; 2754cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2755cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2756cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2757cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2758cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2759cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2760cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2761fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2762fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2763cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2764cf5a6209SStefano Zampini } 2765cf5a6209SStefano Zampini 2766cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 27679162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2768cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2769cf5a6209SStefano Zampini const Vec *nearnullvecs; 2770cf5a6209SStefano Zampini Vec *localnearnullsp; 2771cf5a6209SStefano Zampini PetscScalar *array; 2772cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2773cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2774674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2775b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2776674ae819SStefano Zampini PetscScalar *work; 2777674ae819SStefano Zampini PetscReal *singular_vals; 2778674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2779674ae819SStefano Zampini PetscReal *rwork; 2780674ae819SStefano Zampini #endif 2781674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2782674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2783674ae819SStefano Zampini #else 2784964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2785964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2786674ae819SStefano Zampini #endif 2787674ae819SStefano Zampini 2788674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2789d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2790d06fc5fdSStefano Zampini /* free unneeded index sets */ 2791d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2792d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2793674ae819SStefano Zampini } 2794d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2795d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2796d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2797d06fc5fdSStefano Zampini } 2798d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2799d06fc5fdSStefano Zampini n_ISForEdges = 0; 2800d06fc5fdSStefano Zampini } 2801d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2802d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2803d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2804d06fc5fdSStefano Zampini } 2805d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2806d06fc5fdSStefano Zampini n_ISForFaces = 0; 2807d06fc5fdSStefano Zampini } 280870022509SStefano Zampini 280970022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 281070022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 281170022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 281270022509SStefano Zampini if (pcbddc->NullSpace) { 281370022509SStefano Zampini PetscBool tbool[2],gbool[2]; 281470022509SStefano Zampini 281570022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2816b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2817d06fc5fdSStefano Zampini if (!ISForEdges) { 2818d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2819d06fc5fdSStefano Zampini } 2820b8ffe317SStefano Zampini } 2821d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2822d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2823d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2824d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2825d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 282698a51de6SStefano Zampini } 282770022509SStefano Zampini #endif 282808122e43SStefano Zampini 2829674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2830674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2831674ae819SStefano Zampini if (nearnullsp) { 2832674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2833f4ddd8eeSStefano Zampini /* remove any stored info */ 2834f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2835f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2836f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2837f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2838f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2839473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2840f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2841f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2842f4ddd8eeSStefano Zampini } 2843984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2844984c4197SStefano Zampini nnsp_size = 0; 2845674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2846674ae819SStefano Zampini } 2847984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2848984c4197SStefano Zampini max_constraints = nnsp_size; 2849984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2850984c4197SStefano Zampini 2851674ae819SStefano Zampini /* 2852674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 28539162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 28549162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 28559162d606SStefano Zampini There can be multiple constraints per connected component 2856674ae819SStefano Zampini */ 2857674ae819SStefano Zampini n_vertices = 0; 2858674ae819SStefano Zampini if (ISForVertices) { 2859674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2860674ae819SStefano Zampini } 28619162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 28629162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 28639162d606SStefano Zampini 28649162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 28659162d606SStefano Zampini total_counts *= max_constraints; 2866674ae819SStefano Zampini total_counts += n_vertices; 28674641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 28689162d606SStefano Zampini 2869674ae819SStefano Zampini total_counts = 0; 2870674ae819SStefano Zampini max_size_of_constraint = 0; 2871674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 28729162d606SStefano Zampini IS used_is; 2873674ae819SStefano Zampini if (i<n_ISForEdges) { 28749162d606SStefano Zampini used_is = ISForEdges[i]; 2875674ae819SStefano Zampini } else { 28769162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2877674ae819SStefano Zampini } 28789162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2879674ae819SStefano Zampini total_counts += j; 2880674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2881674ae819SStefano Zampini } 28829162d606SStefano 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); 28839162d606SStefano Zampini 2884984c4197SStefano Zampini /* get local part of global near null space vectors */ 2885785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2886984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2887984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2888e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2889e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2890984c4197SStefano Zampini } 2891674ae819SStefano Zampini 2892242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2893242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2894a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2895242a89d7SStefano Zampini 2896984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2897a773dcb8SStefano Zampini if (!skip_lapack) { 2898674ae819SStefano Zampini PetscScalar temp_work; 2899911cabfeSStefano Zampini 2900674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2901984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2902785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2903785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2904785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2905674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2906785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2907674ae819SStefano Zampini #endif 2908674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2909c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2910c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2911674ae819SStefano Zampini lwork = -1; 2912674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2913674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2914c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2915674ae819SStefano Zampini #else 2916c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2917674ae819SStefano Zampini #endif 2918674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2919984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2920674ae819SStefano Zampini #else /* on missing GESVD */ 2921674ae819SStefano Zampini /* SVD */ 2922674ae819SStefano Zampini PetscInt max_n,min_n; 2923674ae819SStefano Zampini max_n = max_size_of_constraint; 2924984c4197SStefano Zampini min_n = max_constraints; 2925984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2926674ae819SStefano Zampini min_n = max_size_of_constraint; 2927984c4197SStefano Zampini max_n = max_constraints; 2928674ae819SStefano Zampini } 2929785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2930674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2931785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2932674ae819SStefano Zampini #endif 2933674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2934674ae819SStefano Zampini lwork = -1; 2935e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2936e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2937b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2938674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2939674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 29409162d606SStefano 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)); 2941674ae819SStefano Zampini #else 29429162d606SStefano 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)); 2943674ae819SStefano Zampini #endif 2944674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2945984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2946984c4197SStefano Zampini #endif /* on missing GESVD */ 2947674ae819SStefano Zampini /* Allocate optimal workspace */ 2948674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2949854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2950674ae819SStefano Zampini } 2951674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2952674ae819SStefano Zampini total_counts = 0; 29539162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 29549162d606SStefano Zampini constraints_data_ptr[0] = 0; 2955674ae819SStefano Zampini /* vertices */ 29569162d606SStefano Zampini if (n_vertices) { 2957674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 29589162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2959674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 29609162d606SStefano Zampini constraints_n[total_counts] = 1; 29619162d606SStefano Zampini constraints_data[total_counts] = 1.0; 29629162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 29639162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2964674ae819SStefano Zampini total_counts++; 2965674ae819SStefano Zampini } 2966674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2967674ae819SStefano Zampini n_vertices = total_counts; 2968674ae819SStefano Zampini } 2969984c4197SStefano Zampini 2970674ae819SStefano Zampini /* edges and faces */ 29719162d606SStefano Zampini total_counts_cc = total_counts; 2972911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 29739162d606SStefano Zampini IS used_is; 29749162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 29759162d606SStefano Zampini 2976911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 29779162d606SStefano Zampini used_is = ISForEdges[ncc]; 2978984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2979674ae819SStefano Zampini } else { 29809162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2981984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2982674ae819SStefano Zampini } 2983674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 29849162d606SStefano Zampini 29859162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 29869162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2987984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2988984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2989674ae819SStefano Zampini if (nnsp_has_cnst) { 29905b08dc53SStefano Zampini PetscScalar quad_value; 29919162d606SStefano Zampini 29929162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 29939162d606SStefano Zampini idxs_copied = PETSC_TRUE; 29949162d606SStefano Zampini 2995a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2996674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2997a773dcb8SStefano Zampini } else { 2998a773dcb8SStefano Zampini quad_value = 1.0; 2999a773dcb8SStefano Zampini } 3000674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 30019162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3002674ae819SStefano Zampini } 30039162d606SStefano Zampini temp_constraints++; 3004674ae819SStefano Zampini total_counts++; 3005674ae819SStefano Zampini } 3006674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3007984c4197SStefano Zampini PetscReal real_value; 30089162d606SStefano Zampini PetscScalar *ptr_to_data; 30099162d606SStefano Zampini 3010984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 30119162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3012674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 30139162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3014674ae819SStefano Zampini } 3015984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3016984c4197SStefano Zampini /* check if array is null on the connected component */ 3017e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 30189162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 30195b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3020674ae819SStefano Zampini temp_constraints++; 3021674ae819SStefano Zampini total_counts++; 30229162d606SStefano Zampini if (!idxs_copied) { 30239162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 30249162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3025674ae819SStefano Zampini } 3026674ae819SStefano Zampini } 30279162d606SStefano Zampini } 30289162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 302945a1bb75SStefano Zampini valid_constraints = temp_constraints; 3030eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3031a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 30329162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 30339162d606SStefano Zampini 30349162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3035a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 30369162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3037a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 30389162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3039a773dcb8SStefano Zampini } else { /* perform SVD */ 3040984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 30419162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3042674ae819SStefano Zampini 3043674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3044984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3045984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3046984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3047984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3048984c4197SStefano Zampini from that computed using LAPACKgesvd 3049984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3050984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3051984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3052674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3053e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3054984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3055674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3056674ae819SStefano Zampini for (k=0;k<j+1;k++) { 30579162d606SStefano 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)); 3058674ae819SStefano Zampini } 3059674ae819SStefano Zampini } 3060e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3061e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3062e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3063674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3064c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3065674ae819SStefano Zampini #else 3066c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3067674ae819SStefano Zampini #endif 3068674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3069984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3070984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3071674ae819SStefano Zampini j = 0; 3072984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3073674ae819SStefano Zampini total_counts = total_counts-j; 307445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3075e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3076c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3077c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3078c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3079c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3080c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3081c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3082674ae819SStefano Zampini if (j<temp_constraints) { 3083984c4197SStefano Zampini PetscInt ii; 3084984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3085674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30869162d606SStefano 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)); 3087674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3088984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3089674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 30909162d606SStefano 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]; 3091674ae819SStefano Zampini } 3092674ae819SStefano Zampini } 3093674ae819SStefano Zampini } 3094674ae819SStefano Zampini #else /* on missing GESVD */ 3095e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3096e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3097b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3098674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3099674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 31009162d606SStefano 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)); 3101674ae819SStefano Zampini #else 31029162d606SStefano 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)); 3103674ae819SStefano Zampini #endif 3104984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3105674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3106984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3107e310c8b4SStefano Zampini k = temp_constraints; 3108e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3109674ae819SStefano Zampini j = 0; 3110e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 311145a1bb75SStefano Zampini valid_constraints = k-j; 3112911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3113984c4197SStefano Zampini #endif /* on missing GESVD */ 3114674ae819SStefano Zampini } 3115a773dcb8SStefano Zampini } 31169162d606SStefano Zampini /* update pointers information */ 31179162d606SStefano Zampini if (valid_constraints) { 31189162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 31199162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 31209162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 31219162d606SStefano Zampini /* set change_of_basis flag */ 312245a1bb75SStefano Zampini if (boolforchange) { 3123b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 31249162d606SStefano Zampini } 3125b3d85658SStefano Zampini total_counts_cc++; 312645a1bb75SStefano Zampini } 312745a1bb75SStefano Zampini } 3128984c4197SStefano Zampini /* free workspace */ 31298f1c130eSStefano Zampini if (!skip_lapack) { 3130984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3131984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3132984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3133984c4197SStefano Zampini #endif 3134984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3135984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3136984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3137984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3138984c4197SStefano Zampini #endif 3139984c4197SStefano Zampini } 3140984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3141984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3142984c4197SStefano Zampini } 3143984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3144cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3145cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3146cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3147cf5a6209SStefano Zampini } 3148cf5a6209SStefano Zampini if (n_ISForFaces) { 3149cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3150cf5a6209SStefano Zampini } 3151cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3152cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3153cf5a6209SStefano Zampini } 3154cf5a6209SStefano Zampini if (n_ISForEdges) { 3155cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3156cf5a6209SStefano Zampini } 3157cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 315808122e43SStefano Zampini } else { 315908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3160984c4197SStefano Zampini 316108122e43SStefano Zampini total_counts = 0; 316208122e43SStefano Zampini n_vertices = 0; 3163d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3164d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 316508122e43SStefano Zampini } 316608122e43SStefano Zampini max_constraints = 0; 31679162d606SStefano Zampini total_counts_cc = 0; 316808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 316908122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 31709162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 317108122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 317208122e43SStefano Zampini } 31739162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 31749162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 31759162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 31769162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 317774d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 31789162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 31799162d606SStefano Zampini total_counts_cc = 0; 31809162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 31819162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 31829162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 318308122e43SStefano Zampini } 318408122e43SStefano Zampini } 31859162d606SStefano Zampini #if 0 31869162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 31879162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 31889162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 31899162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 31909162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 31919162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 31929162d606SStefano Zampini } 31939162d606SStefano Zampini printf("\n"); 31949162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 31959162d606SStefano Zampini } 31961b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 31978bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 31981b968477SStefano Zampini } 31991b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 32008bec7fa6SStefano 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]); 32011b968477SStefano Zampini } 320208122e43SStefano Zampini #endif 320308122e43SStefano Zampini 32048bec7fa6SStefano Zampini max_size_of_constraint = 0; 32059162d606SStefano 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]); 32069162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 320708122e43SStefano Zampini /* Change of basis */ 3208b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 320908122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 321008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 321108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3212b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 321308122e43SStefano Zampini } 321408122e43SStefano Zampini } 321508122e43SStefano Zampini } 321608122e43SStefano Zampini } 3217984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 32184f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 321908122e43SStefano Zampini 32209162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 32219162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 32229162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 32239162d606SStefano 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); 322408122e43SStefano Zampini } 3225674ae819SStefano Zampini 3226674ae819SStefano Zampini /* Create constraint matrix */ 3227674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 322816f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3229984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3230984c4197SStefano Zampini 3231984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3232a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3233a717540cSStefano Zampini qr_needed = PETSC_FALSE; 323474d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3235984c4197SStefano Zampini total_primal_vertices=0; 3236b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 32379162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 32389162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3239984c4197SStefano Zampini if (size_of_constraint == 1) { 32409162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 3241b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 324264efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 32439162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 32449162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 3245a717540cSStefano Zampini } 3246b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 324774d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 3248a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 3249a717540cSStefano Zampini qr_needed = PETSC_TRUE; 3250a717540cSStefano Zampini } 3251fa434743SStefano Zampini } else { 3252b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 3253fa434743SStefano Zampini } 3254a717540cSStefano Zampini } 3255b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 3256b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 3257674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 325870022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3259b3d85658SStefano Zampini 32604f1b2e48SStefano 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); 32610e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 32620e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 3263984c4197SStefano Zampini 3264984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 326574d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 3266785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 3267984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 326874d5cdf7SStefano Zampini 3269984c4197SStefano Zampini j = total_primal_vertices; 327074d5cdf7SStefano Zampini total_counts = total_primal_vertices; 3271b3d85658SStefano Zampini cum = total_primal_vertices; 32729162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32734641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 3274b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 3275b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 3276b3d85658SStefano Zampini cum++; 32779162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 327874d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 327974d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 328074d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 328174d5cdf7SStefano Zampini } 32829162d606SStefano Zampini j += constraints_n[i]; 3283674ae819SStefano Zampini } 3284674ae819SStefano Zampini } 3285674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 3286674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3287088faed8SStefano Zampini 3288674ae819SStefano Zampini /* set values in constraint matrix */ 3289984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 32900e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3291674ae819SStefano Zampini } 3292984c4197SStefano Zampini total_counts = total_primal_vertices; 32939162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32944641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 32959162d606SStefano Zampini PetscInt *cols; 32969162d606SStefano Zampini 32979162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 32989162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 32999162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 33009162d606SStefano Zampini PetscInt row = total_counts+k; 33019162d606SStefano Zampini PetscScalar *vals; 33029162d606SStefano Zampini 33039162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 33049162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 33059162d606SStefano Zampini } 33069162d606SStefano Zampini total_counts += constraints_n[i]; 3307674ae819SStefano Zampini } 3308674ae819SStefano Zampini } 3309674ae819SStefano Zampini /* assembling */ 3310674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3311674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3312088faed8SStefano Zampini 3313984c4197SStefano Zampini /* 331445a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3315984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 3316984c4197SStefano Zampini */ 3317674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 3318674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 3319026de310SStefano Zampini /* dual and primal dofs on a single cc */ 3320984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 3321984c4197SStefano Zampini /* working stuff for GEQRF */ 332281d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 3323984c4197SStefano Zampini PetscBLASInt lqr_work; 3324984c4197SStefano Zampini /* working stuff for UNGQR */ 3325984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 3326984c4197SStefano Zampini PetscBLASInt lgqr_work; 3327984c4197SStefano Zampini /* working stuff for TRTRS */ 3328984c4197SStefano Zampini PetscScalar *trs_rhs; 33293f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 3330984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 3331984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 3332984c4197SStefano Zampini PetscScalar *start_vals; 3333984c4197SStefano Zampini /* working stuff for values insertion */ 33344641a718SStefano Zampini PetscBT is_primal; 333564efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 3336906d46d4SStefano Zampini /* matrix sizes */ 3337906d46d4SStefano Zampini PetscInt global_size,local_size; 3338906d46d4SStefano Zampini /* temporary change of basis */ 3339906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 3340cf5a6209SStefano Zampini /* extra space for debugging */ 3341cf5a6209SStefano Zampini PetscScalar *dbg_work; 3342984c4197SStefano Zampini 3343906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 3344906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 334516f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 3346bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3347906d46d4SStefano Zampini /* nonzeros for local mat */ 3348bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 3349bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 33509162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 3351a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 33529162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3353a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 33549162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3355a717540cSStefano Zampini } else { 33569162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 33579162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3358a717540cSStefano Zampini } 3359a717540cSStefano Zampini } 3360a717540cSStefano Zampini } 3361906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3362bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3363a717540cSStefano Zampini /* Set initial identity in the matrix */ 3364bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3365906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3366a717540cSStefano Zampini } 3367a717540cSStefano Zampini 3368a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3369a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3370a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3371a717540cSStefano Zampini } 3372a717540cSStefano Zampini 3373a717540cSStefano Zampini 3374a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3375a717540cSStefano Zampini /* 3376a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3377a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3378a717540cSStefano Zampini 3379a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3380a717540cSStefano Zampini 3381a6b551f4SStefano 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) 3382a6b551f4SStefano Zampini 3383a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3384a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3385a717540cSStefano Zampini | ... | 3386a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3387a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3388a717540cSStefano Zampini 3389a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3390a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3391a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3392a6b551f4SStefano Zampini 3393a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3394a717540cSStefano Zampini */ 3395a717540cSStefano Zampini if (qr_needed) { 3396984c4197SStefano Zampini /* space to store Q */ 3397854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3398984c4197SStefano Zampini /* first we issue queries for optimal work */ 33993f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 34003f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 34013f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3402984c4197SStefano Zampini lqr_work = -1; 34033f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3404984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3405984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3406785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3407984c4197SStefano Zampini lgqr_work = -1; 34083f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 34093f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 34103f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 34113f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34123f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 34133f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3414984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3415984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3416785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3417984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3418785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3419984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3420785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3421a717540cSStefano Zampini /* allocating workspace for check */ 3422a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3423cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3424a717540cSStefano Zampini } 3425a717540cSStefano Zampini } 3426984c4197SStefano Zampini /* array to store whether a node is primal or not */ 34274641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3428473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 34290e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 343039e2fb2aSStefano Zampini if (i != total_primal_vertices) { 343139e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 34324641a718SStefano Zampini } 343339e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 343439e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 343539e2fb2aSStefano Zampini } 343639e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3437984c4197SStefano Zampini 3438a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 34399162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 34409162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 34414641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3442984c4197SStefano Zampini /* get constraint info */ 34439162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3444984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3445984c4197SStefano Zampini 3446984c4197SStefano Zampini if (pcbddc->dbg_flag) { 34479162d606SStefano 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); 3448674ae819SStefano Zampini } 3449984c4197SStefano Zampini 3450fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3451a717540cSStefano Zampini 3452a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3453a717540cSStefano Zampini if (pcbddc->dbg_flag) { 34549162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3455a717540cSStefano Zampini } 3456984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 34579162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3458984c4197SStefano Zampini 3459984c4197SStefano Zampini /* compute QR decomposition of constraints */ 34603f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34613f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34623f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3463674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34643f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3465984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3466674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3467984c4197SStefano Zampini 3468984c4197SStefano Zampini /* explictly compute R^-T */ 3469984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3470984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 34713f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34723f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 34733f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34743f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3475984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34763f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3477984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3478984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3479984c4197SStefano Zampini 3480a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 34813f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34823f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34833f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34843f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3485984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34863f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3487984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3488984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3489984c4197SStefano Zampini 3490984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3491984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3492984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 34933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34953f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34963f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34973f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 34983f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3499984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 35009162d606SStefano 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)); 3501984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 35029162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3503984c4197SStefano Zampini 3504984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 35059162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3506984c4197SStefano Zampini /* insert cols for primal dofs */ 3507984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3508984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 35099162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3510906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3511984c4197SStefano Zampini } 3512984c4197SStefano Zampini /* insert cols for dual dofs */ 3513984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 35149162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3515984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 35169162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3517906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3518984c4197SStefano Zampini j++; 3519674ae819SStefano Zampini } 3520674ae819SStefano Zampini } 3521984c4197SStefano Zampini 3522984c4197SStefano Zampini /* check change of basis */ 3523984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3524984c4197SStefano Zampini PetscInt ii,jj; 3525984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3526c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3527c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3528c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3529c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3530c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3531c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3532984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3533cf5a6209SStefano 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)); 3534984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3535984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3536984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3537cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3538cf5a6209SStefano 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; 3539674ae819SStefano Zampini } 3540674ae819SStefano Zampini } 3541984c4197SStefano Zampini if (!valid_qr) { 354222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3543984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3544984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3545cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3546cf5a6209SStefano 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])); 3547674ae819SStefano Zampini } 3548cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3549cf5a6209SStefano 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])); 3550984c4197SStefano Zampini } 3551984c4197SStefano Zampini } 3552984c4197SStefano Zampini } 3553674ae819SStefano Zampini } else { 355422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3555674ae819SStefano Zampini } 3556674ae819SStefano Zampini } 3557a717540cSStefano Zampini } else { /* simple transformation block */ 3558a717540cSStefano Zampini PetscInt row,col; 3559a6b551f4SStefano Zampini PetscScalar val,norm; 3560a6b551f4SStefano Zampini 3561a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 35629162d606SStefano 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)); 3563a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 35649162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 35659162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3566bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 35679162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3568906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 35699162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3570a717540cSStefano Zampini } else { 3571a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 35729162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3573a717540cSStefano Zampini if (row != col) { 35749162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3575a717540cSStefano Zampini } else { 35769162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3577a717540cSStefano Zampini } 3578906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3579a717540cSStefano Zampini } 3580a717540cSStefano Zampini } 3581a717540cSStefano Zampini } 358298a51de6SStefano Zampini if (pcbddc->dbg_flag) { 358322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3584a717540cSStefano Zampini } 3585674ae819SStefano Zampini } 3586984c4197SStefano Zampini } else { 3587984c4197SStefano Zampini if (pcbddc->dbg_flag) { 35889162d606SStefano 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); 3589674ae819SStefano Zampini } 3590674ae819SStefano Zampini } 3591674ae819SStefano Zampini } 3592a717540cSStefano Zampini 3593a717540cSStefano Zampini /* free workspace */ 3594a717540cSStefano Zampini if (qr_needed) { 3595984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3596cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3597984c4197SStefano Zampini } 3598984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3599984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3600984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3601984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3602984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3603674ae819SStefano Zampini } 3604a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3605906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3606906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3607906d46d4SStefano Zampini 3608906d46d4SStefano Zampini /* assembling of global change of variable */ 3609bbb9e6c6SStefano Zampini { 3610bbb9e6c6SStefano Zampini Mat tmat; 361116f15bc4SStefano Zampini PetscInt bs; 361216f15bc4SStefano Zampini 3613906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3614906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3615bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3616bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3617bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3618bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 361916f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 362016f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3621906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3622bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3623bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3624bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3625bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3626bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3627e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3628e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3629bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3630bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3631906d46d4SStefano Zampini } 3632906d46d4SStefano Zampini /* check */ 3633906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3634906d46d4SStefano Zampini PetscReal error; 3635906d46d4SStefano Zampini Vec x,x_change; 3636906d46d4SStefano Zampini 3637906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3638906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3639906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3640906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3641e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3642e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3643bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 3644e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3645e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3646906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 3647906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3648906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3649906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3650bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 3651906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3652906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3653906d46d4SStefano Zampini } 3654b96c3477SStefano Zampini 3655b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 3656b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3657b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 3658b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 3659ac632422SStefano Zampini Mat S_new,tmat; 3660b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 3661b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 3662b087196eSStefano Zampini const PetscScalar *array; 3663b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 3664b087196eSStefano Zampini PetscInt i,n_V; 3665bbb9e6c6SStefano Zampini 3666bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 36676816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 3668b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 3669b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 3670b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 3671b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 3672bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 3673b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 3674ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3675b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 3676ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3677b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3678b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 3679b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3680b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3681b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 3682b087196eSStefano Zampini for (i=0;i<n_V;i++) { 3683b087196eSStefano Zampini PetscScalar val; 3684b087196eSStefano Zampini PetscInt idx; 3685b087196eSStefano Zampini 3686b087196eSStefano Zampini idx = idxs_V[i]; 3687b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 3688b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 3689b087196eSStefano Zampini } 3690b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3691b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3692ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 3693ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3694ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 3695ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3696b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 3697ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3698b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3699ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 3700ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3701ac632422SStefano Zampini } 3702b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 3703b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3704b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3705b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3706b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 3707b96c3477SStefano Zampini } 3708b96c3477SStefano Zampini } 3709906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 3710906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 3711b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3712b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 3713b9b85e73SStefano Zampini } 3714906d46d4SStefano Zampini 3715906d46d4SStefano Zampini /* set up change of basis context */ 3716906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 3717906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 3718906d46d4SStefano Zampini 3719906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 3720906d46d4SStefano Zampini PetscInt global_size,local_size; 3721906d46d4SStefano Zampini 3722906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3723906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3724906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 3725906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3726906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 3727906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 3728906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3729906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3730906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3731906d46d4SStefano Zampini } else { 3732906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3733906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3734906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3735906d46d4SStefano Zampini } 3736906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3737906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3738906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3739906d46d4SStefano Zampini } else { 3740906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3741906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3742906d46d4SStefano Zampini } 3743906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3744906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3745906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3746906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3747b9b85e73SStefano Zampini } 3748a717540cSStefano Zampini 37494f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 37504f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 37514f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 37524f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 3753019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 3754019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 3755019a44ceSStefano Zampini pcbddc->local_primal_size++; 3756019a44ceSStefano Zampini } 3757019a44ceSStefano Zampini 3758019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 3759727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3760727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 37619f47a83aSStefano 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); 3762c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 37630e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 37649f47a83aSStefano 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); 3765727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3766727cdba6SStefano Zampini } 37670e6343abSStefano Zampini } 37680e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3769727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3770727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3771727cdba6SStefano Zampini 3772a717540cSStefano Zampini /* flush dbg viewer */ 3773b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3774b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3775b8ffe317SStefano Zampini } 3776a717540cSStefano Zampini 3777e310c8b4SStefano Zampini /* free workspace */ 3778a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 37794641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 378008122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 37819162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 37829162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 378308122e43SStefano Zampini } else { 37849162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 37859162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 37869162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 378708122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 378808122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 37899162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 37909162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 379108122e43SStefano Zampini } 3792674ae819SStefano Zampini PetscFunctionReturn(0); 3793674ae819SStefano Zampini } 3794674ae819SStefano Zampini 3795674ae819SStefano Zampini #undef __FUNCT__ 3796674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3797674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3798674ae819SStefano Zampini { 3799674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3800674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3801674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 38027fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3803674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3804674ae819SStefano Zampini 3805674ae819SStefano Zampini PetscFunctionBegin; 38068e61c736SStefano Zampini /* Reset previously computed graph */ 38078e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3808674ae819SStefano Zampini /* Init local Graph struct */ 38097fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 38103bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3811674ae819SStefano Zampini 3812575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 38135099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 38145099eff2SStefano 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); 3815575ad6abSStefano Zampini } 38169577ea80SStefano Zampini 3817674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 38184d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 38194d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 38204d379d7bSStefano Zampini PetscInt nvtxs; 3821e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3822674ae819SStefano Zampini 38234d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 38242fffb893SStefano Zampini 38252fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 38262fffb893SStefano Zampini if (flg_row) { 38274d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3828b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 38292fffb893SStefano Zampini } 38302fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 38319b28b941SStefano 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 */ 38324d379d7bSStefano Zampini IS is_dummy; 38334d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 38344d379d7bSStefano Zampini PetscInt j,sum; 38354d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 38364d379d7bSStefano Zampini const PetscInt *idxs; 38374d379d7bSStefano Zampini PCBDDCGraph graph; 38384d379d7bSStefano Zampini PetscBT is_on_boundary; 38394d379d7bSStefano Zampini 38404d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 38414d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 38424d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 38434d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 38447fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 38454d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3846e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3847e496cd5dSStefano Zampini if (flg_row) { 38484d379d7bSStefano Zampini graph->xadj = xadj; 38494d379d7bSStefano Zampini graph->adjncy = adjncy; 3850e496cd5dSStefano Zampini } 38514d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 38524d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3853e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 38544d379d7bSStefano Zampini 38554d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 38569b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 38574d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38584d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 38594d379d7bSStefano Zampini } 38604d379d7bSStefano Zampini } 38614d379d7bSStefano Zampini 3862e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 38634d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38644d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 38654d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 38664d379d7bSStefano Zampini } 38674d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38684d379d7bSStefano Zampini 3869e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 38704d379d7bSStefano Zampini sum = 0; 38714d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38724d379d7bSStefano Zampini PetscInt sizecc = 0; 38734d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38744d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38754d379d7bSStefano Zampini sizecc++; 38764d379d7bSStefano Zampini } 38774d379d7bSStefano Zampini } 38784d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38794d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38804d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 38814d379d7bSStefano Zampini } 38824d379d7bSStefano Zampini } 38834d379d7bSStefano Zampini sum += sizecc*sizecc; 38844d379d7bSStefano Zampini } 38854d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 38864d379d7bSStefano Zampini sum = 0; 3887e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 38884d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 38894d379d7bSStefano Zampini cxadj[i] = sum; 38904d379d7bSStefano Zampini sum += temp; 38914d379d7bSStefano Zampini } 3892e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 38934d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38944d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38954d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38964d379d7bSStefano Zampini PetscInt k,sizecc = 0; 38974d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 38984d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 38994d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 39004d379d7bSStefano Zampini sizecc++; 39014d379d7bSStefano Zampini } 39024d379d7bSStefano Zampini } 39034d379d7bSStefano Zampini } 39044d379d7bSStefano Zampini } 39054d379d7bSStefano Zampini } 39069b28b941SStefano Zampini if (sum) { 3907e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 39084d379d7bSStefano Zampini } else { 39094d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 39104d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 39114d379d7bSStefano Zampini } 39124d379d7bSStefano Zampini graph->xadj = 0; 39134d379d7bSStefano Zampini graph->adjncy = 0; 39144d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 39154d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 39164d379d7bSStefano Zampini } 3917674ae819SStefano Zampini } 39189b28b941SStefano Zampini if (pcbddc->dbg_flag) { 39199b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3920674ae819SStefano Zampini } 3921674ae819SStefano Zampini 392263602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3923674ae819SStefano Zampini vertex_size = 1; 392463602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 392563602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 392695ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 392763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3928e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 392963602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3930674ae819SStefano Zampini } 393163602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 393263602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 393363602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3934674ae819SStefano Zampini } 393563602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3936674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 393763602bcaSStefano Zampini } else { 393863602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 393963602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3940854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 394163602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 394263602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 394363602bcaSStefano Zampini } 394463602bcaSStefano Zampini } 3945674ae819SStefano Zampini } 3946674ae819SStefano Zampini 3947674ae819SStefano Zampini /* Setup of Graph */ 3948785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3949e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3950785d1243SStefano Zampini } 3951785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3952e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3953785d1243SStefano Zampini } 395430368db7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { /* need to convert from global to local */ 395530368db7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 395630368db7SStefano Zampini } 395730368db7SStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3958674ae819SStefano Zampini 39594f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 39604f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 39614f1b2e48SStefano Zampini PetscInt *local_subs; 39624f1b2e48SStefano Zampini 39634f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 39644f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 39654f1b2e48SStefano Zampini const PetscInt *idxs; 39664f1b2e48SStefano Zampini PetscInt nl,j; 39674f1b2e48SStefano Zampini 39684f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 39694f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39704f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 39714f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 39724f1b2e48SStefano Zampini } 39734f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39744f1b2e48SStefano Zampini } 39754f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 39764f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 39774f1b2e48SStefano Zampini } 39784f1b2e48SStefano Zampini 3979674ae819SStefano Zampini /* Graph's connected components analysis */ 3980674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3981674ae819SStefano Zampini 3982674ae819SStefano Zampini /* print some info to stdout */ 3983674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3984302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3985674ae819SStefano Zampini } 3986fb180af4SStefano Zampini 3987fb180af4SStefano Zampini /* mark topography has done */ 3988fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3989674ae819SStefano Zampini PetscFunctionReturn(0); 3990674ae819SStefano Zampini } 3991674ae819SStefano Zampini 3992dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3993674ae819SStefano Zampini #undef __FUNCT__ 3994674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3995dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3996674ae819SStefano Zampini { 3997dc456d91SStefano Zampini PetscSF sf; 3998dc456d91SStefano Zampini PetscLayout map; 3999dc456d91SStefano Zampini const PetscInt *idxs; 4000dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4001dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4002dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4003dc456d91SStefano Zampini PetscMPIInt commsize; 4004674ae819SStefano Zampini PetscBool first_found; 4005674ae819SStefano Zampini PetscErrorCode ierr; 4006674ae819SStefano Zampini 4007674ae819SStefano Zampini PetscFunctionBegin; 4008dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4009dc456d91SStefano Zampini if (subset_mult) { 4010dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4011dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4012dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4013674ae819SStefano Zampini } 4014dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4015dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4016dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4017dc456d91SStefano Zampini for (i=0;i<n;i++) { 4018dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4019dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4020674ae819SStefano Zampini } 4021dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4022dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4023dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4024dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4025dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4026dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4027dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4028dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4029dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4030dc456d91SStefano Zampini 4031dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4032dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4033dc456d91SStefano Zampini if (subset_mult) { 4034dc456d91SStefano Zampini const PetscInt* idxs_mult; 4035dc456d91SStefano Zampini 4036dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4037dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4038dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4039674ae819SStefano Zampini } else { 4040dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4041674ae819SStefano Zampini } 4042dc456d91SStefano Zampini /* local size of new subset */ 4043dc456d91SStefano Zampini n_n = 0; 4044dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4045dc456d91SStefano Zampini 4046dc456d91SStefano Zampini /* global indexes in layout */ 4047dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4048dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4049dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4050dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4051dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4052dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4053dc456d91SStefano Zampini 4054dc456d91SStefano Zampini /* reduce from leaves to roots */ 4055dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 405664a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 405764a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4058dc456d91SStefano Zampini 4059dc456d91SStefano Zampini /* count indexes in local part of layout */ 4060674ae819SStefano Zampini nlocals = 0; 4061674ae819SStefano Zampini first_index = -1; 4062674ae819SStefano Zampini first_found = PETSC_FALSE; 4063dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4064dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4065674ae819SStefano Zampini first_found = PETSC_TRUE; 4066674ae819SStefano Zampini first_index = i; 4067674ae819SStefano Zampini } 4068dc456d91SStefano Zampini nlocals += root_data[i]; 4069674ae819SStefano Zampini } 4070dc456d91SStefano Zampini 4071dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 40725fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4073dc456d91SStefano Zampini start = 0; 407464a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40755fa240b1SStefano Zampini #else 407664a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40775fa240b1SStefano Zampini start = start-nlocals; 40785fa240b1SStefano Zampini #endif 40795fa240b1SStefano Zampini 4080dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4081dc456d91SStefano Zampini *N_n = start + nlocals; 4082dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4083dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4084674ae819SStefano Zampini } 40855fa240b1SStefano Zampini 40865fa240b1SStefano Zampini /* adapt root data with cumulative */ 4087674ae819SStefano Zampini if (first_found) { 4088dc456d91SStefano Zampini PetscInt old_index; 4089dc456d91SStefano Zampini 4090dc456d91SStefano Zampini root_data[first_index] += start; 4091674ae819SStefano Zampini old_index = first_index; 4092dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4093dc456d91SStefano Zampini if (root_data[i]) { 4094dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4095674ae819SStefano Zampini old_index = i; 4096674ae819SStefano Zampini } 4097674ae819SStefano Zampini } 4098674ae819SStefano Zampini } 4099dc456d91SStefano Zampini 4100dc456d91SStefano Zampini /* from roots to leaves */ 4101dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4102dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4103dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4104dc456d91SStefano Zampini 4105dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4106dc456d91SStefano Zampini if (subset_mult) { 4107dc456d91SStefano Zampini const PetscInt* idxs_mult; 4108dc456d91SStefano Zampini PetscInt cum; 4109dc456d91SStefano Zampini 4110dc456d91SStefano Zampini cum = 0; 4111dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4112dc456d91SStefano Zampini for (i=0;i<n;i++) { 4113dc456d91SStefano Zampini PetscInt j; 4114dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4115674ae819SStefano Zampini } 4116dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4117674ae819SStefano Zampini } else { 4118dc456d91SStefano Zampini for (i=0;i<n;i++) { 4119dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4120674ae819SStefano Zampini } 4121674ae819SStefano Zampini } 4122dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4123dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4124674ae819SStefano Zampini PetscFunctionReturn(0); 4125674ae819SStefano Zampini } 41269a7d3425SStefano Zampini 41279a7d3425SStefano Zampini #undef __FUNCT__ 41289a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 41299a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 41309a7d3425SStefano Zampini { 41319a7d3425SStefano Zampini PetscInt i,j; 41329a7d3425SStefano Zampini PetscScalar *alphas; 41339a7d3425SStefano Zampini PetscErrorCode ierr; 41349a7d3425SStefano Zampini 41359a7d3425SStefano Zampini PetscFunctionBegin; 41369a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4137785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 41389a7d3425SStefano Zampini for (i=0;i<n;i++) { 41399a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 41409a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 41419a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 41429a7d3425SStefano Zampini } 41439a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 41449a7d3425SStefano Zampini PetscFunctionReturn(0); 41459a7d3425SStefano Zampini } 41469a7d3425SStefano Zampini 4147e7931f94SStefano Zampini #undef __FUNCT__ 414870cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 4149b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 4150e7931f94SStefano Zampini { 415152e5ac9dSStefano Zampini IS ranks_send_to; 4152e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4153e7931f94SStefano Zampini PetscMPIInt size,rank,color; 415452e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 415552e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 41563837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 41572b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 4158e7931f94SStefano Zampini PetscSubcomm subcomm; 415952e5ac9dSStefano Zampini PetscErrorCode ierr; 4160a57a6d2fSStefano Zampini 4161e7931f94SStefano Zampini PetscFunctionBegin; 41622b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 41632b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 41642b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 4165e7931f94SStefano Zampini 4166e7931f94SStefano Zampini /* Get info on mapping */ 41673bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 41683bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4169e7931f94SStefano Zampini 4170e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4171785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4172e7931f94SStefano Zampini xadj[0] = 0; 4173e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4174785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4175785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 4176e7931f94SStefano Zampini 41772b510759SStefano Zampini if (threshold) { 4178d023bfaeSStefano Zampini PetscInt xadj_count = 0; 41792b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 4180d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 4181d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4182d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4183d023bfaeSStefano Zampini xadj_count++; 4184e7931f94SStefano Zampini } 4185e7931f94SStefano Zampini } 4186d023bfaeSStefano Zampini xadj[1] = xadj_count; 4187c8587f34SStefano Zampini } else { 4188e7931f94SStefano Zampini if (xadj[1]) { 4189e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 4190e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 4191c8587f34SStefano Zampini } 4192e7931f94SStefano Zampini } 41933bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4194e7931f94SStefano Zampini if (use_square) { 4195e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4196e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 4197e7931f94SStefano Zampini } 4198e7931f94SStefano Zampini } 4199e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4200e7931f94SStefano Zampini 42013837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4202e7931f94SStefano Zampini 4203e7931f94SStefano Zampini /* 4204e7931f94SStefano Zampini Restrict work on active processes only. 4205e7931f94SStefano Zampini */ 4206e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 4207e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 4208e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 42092b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 4210d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4211e7931f94SStefano Zampini if (color) { 4212e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4213e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4214e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4215c8587f34SStefano Zampini } else { 421652e5ac9dSStefano Zampini Mat subdomain_adj; 421752e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 421852e5ac9dSStefano Zampini MatPartitioning partitioner; 421952e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 422052e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 4221b0c7d250SStefano Zampini PetscBool aggregate; 4222b0c7d250SStefano Zampini 4223306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 4224785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 4225e7931f94SStefano Zampini prank = rank; 4226306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 42278002ef2cSStefano Zampini /* 4228e7931f94SStefano Zampini for (i=0;i<size;i++) { 4229e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 4230c8587f34SStefano Zampini } 42318002ef2cSStefano Zampini */ 4232e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4233e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4234c8587f34SStefano Zampini } 4235e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4236b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 4237b0c7d250SStefano Zampini if (aggregate) { 4238b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4239b0c7d250SStefano Zampini PetscMPIInt nrank; 4240b0c7d250SStefano Zampini PetscScalar *vals; 4241b0c7d250SStefano Zampini 4242b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 4243b0c7d250SStefano Zampini lrows = 0; 4244b0c7d250SStefano Zampini if (nrank<redprocs) { 4245b0c7d250SStefano Zampini lrows = size/redprocs; 4246b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4247b0c7d250SStefano Zampini } 42485fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4249b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4250b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4251b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4252b0c7d250SStefano Zampini row = nrank; 4253b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4254b0c7d250SStefano Zampini cols = adjncy; 4255b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4256b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 4257b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 4258b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4259b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 426052e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 426152e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 426252e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4263b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4264b0c7d250SStefano Zampini } else { 4265306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 4266b0c7d250SStefano Zampini } 426722b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 4268e7931f94SStefano Zampini 4269e7931f94SStefano Zampini /* Partition */ 4270306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 4271e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 4272e7931f94SStefano Zampini if (use_vwgt) { 42733837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 4274e7931f94SStefano Zampini v_wgt[0] = local_size; 4275e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 4276c8587f34SStefano Zampini } 427728143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 427828143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 4279e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 4280e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 428122b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 4282e7931f94SStefano Zampini 428352e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 428452e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 428552e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 428652e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4287b0c7d250SStefano Zampini if (!redprocs) { 4288b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 428928143c3dSStefano Zampini } else { 4290b0c7d250SStefano Zampini PetscInt idxs[1]; 4291b0c7d250SStefano Zampini PetscMPIInt tag; 4292b0c7d250SStefano Zampini MPI_Request *reqs; 4293b0c7d250SStefano Zampini 4294b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 4295b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 4296b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 4297b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 429828143c3dSStefano Zampini } 4299b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 4300b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4301b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 4302b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 4303e7931f94SStefano Zampini } 430452e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4305e7931f94SStefano Zampini /* clean up */ 4306e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 430752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 4308e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 4309e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 4310e7931f94SStefano Zampini } 4311e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 4312e7931f94SStefano Zampini 4313e7931f94SStefano Zampini /* assemble parallel IS for sends */ 4314e7931f94SStefano Zampini i = 1; 4315e7931f94SStefano Zampini if (color) i=0; 4316e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 4317e7931f94SStefano Zampini /* get back IS */ 4318e7931f94SStefano Zampini *is_sends = ranks_send_to; 4319e7931f94SStefano Zampini PetscFunctionReturn(0); 4320e7931f94SStefano Zampini } 4321e7931f94SStefano Zampini 4322e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 4323e7931f94SStefano Zampini 4324e7931f94SStefano Zampini #undef __FUNCT__ 4325e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 432653a05cb3SStefano 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[]) 4327e7931f94SStefano Zampini { 432870cf5478SStefano Zampini Mat local_mat; 4329e7931f94SStefano Zampini IS is_sends_internal; 43309d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 433128143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 43329d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 4333e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 4334e7931f94SStefano Zampini PetscInt* l2gmap_indices; 4335e7931f94SStefano Zampini const PetscInt* is_indices; 4336e7931f94SStefano Zampini MatType new_local_type; 4337e7931f94SStefano Zampini /* buffers */ 4338e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 433928143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 43409d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 4341e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 4342e7931f94SStefano Zampini /* MPI */ 434328143c3dSStefano Zampini MPI_Comm comm,comm_n; 434428143c3dSStefano Zampini PetscSubcomm subcomm; 4345e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 434628143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 434728143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 434828143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 434928143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 435028143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 4351e7931f94SStefano Zampini PetscErrorCode ierr; 4352e7931f94SStefano Zampini 4353e7931f94SStefano Zampini PetscFunctionBegin; 435428143c3dSStefano Zampini /* TODO: add missing checks */ 435528143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 435628143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 435728143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 435828143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 4359e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 436028143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 4361e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4362e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 4363e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 4364e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 4365e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 436628143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 436770cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 436870cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 436928143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 437070cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 437170cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 437270cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 437370cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 437470cf5478SStefano Zampini } 4375e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4376e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4377e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4378e7931f94SStefano Zampini if (!is_sends) { 437928143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4380b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4381c8587f34SStefano Zampini } else { 4382e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4383e7931f94SStefano Zampini is_sends_internal = is_sends; 4384c8587f34SStefano Zampini } 4385e7931f94SStefano Zampini 4386e7931f94SStefano Zampini /* get comm */ 4387a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4388e7931f94SStefano Zampini 4389e7931f94SStefano Zampini /* compute number of sends */ 4390e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4391e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4392e7931f94SStefano Zampini 4393e7931f94SStefano Zampini /* compute number of receives */ 4394e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4395785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4396e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4397e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4398e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4399e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4400e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4401e7931f94SStefano Zampini 440228143c3dSStefano Zampini /* restrict comm if requested */ 440328143c3dSStefano Zampini subcomm = 0; 440428143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 440528143c3dSStefano Zampini if (restrict_comm) { 4406779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4407779c1cceSStefano Zampini 440828143c3dSStefano Zampini color = 0; 440953a05cb3SStefano Zampini if (restrict_full) { 441053a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 441153a05cb3SStefano Zampini } else { 441253a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 441353a05cb3SStefano Zampini } 441428143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 441528143c3dSStefano Zampini subcommsize = commsize - subcommsize; 441628143c3dSStefano Zampini /* check if reuse has been requested */ 441728143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 441828143c3dSStefano Zampini if (*mat_n) { 441928143c3dSStefano Zampini PetscMPIInt subcommsize2; 442028143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 442128143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 442228143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 442328143c3dSStefano Zampini } else { 442428143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 442528143c3dSStefano Zampini } 442628143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4427779c1cceSStefano Zampini PetscMPIInt rank; 4428779c1cceSStefano Zampini 4429779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 443028143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 443128143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 443228143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4433306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 443428143c3dSStefano Zampini } 443528143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 443628143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 443728143c3dSStefano Zampini } else { 443828143c3dSStefano Zampini comm_n = comm; 443928143c3dSStefano Zampini } 444028143c3dSStefano Zampini 4441e7931f94SStefano Zampini /* prepare send/receive buffers */ 4442785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4443e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4444785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4445e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 444628143c3dSStefano Zampini if (nis) { 4447854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 444828143c3dSStefano Zampini } 4449e7931f94SStefano Zampini 445028143c3dSStefano Zampini /* Get data from local matrices */ 4451e7931f94SStefano Zampini if (!isdense) { 4452a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4453e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4454e7931f94SStefano Zampini /* 4455e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4456e7931f94SStefano Zampini send_buffer_idxs should contain: 4457e7931f94SStefano Zampini - MatType_PRIVATE type 4458e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4459e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4460e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4461e7931f94SStefano Zampini */ 4462e7931f94SStefano Zampini } else { 4463e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 44643bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4465854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4466e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4467e7931f94SStefano Zampini send_buffer_idxs[1] = i; 44683bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4469e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 44703bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4471e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4472e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4473e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4474e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4475c8587f34SStefano Zampini } 4476c8587f34SStefano Zampini } 4477e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 447828143c3dSStefano Zampini /* additional is (if any) */ 447928143c3dSStefano Zampini if (nis) { 448028143c3dSStefano Zampini PetscMPIInt psum; 448128143c3dSStefano Zampini PetscInt j; 448228143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 448328143c3dSStefano Zampini PetscInt plen; 448428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 448528143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 448628143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 448728143c3dSStefano Zampini } 4488854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 448928143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 449028143c3dSStefano Zampini PetscInt plen; 449128143c3dSStefano Zampini const PetscInt *is_array_idxs; 449228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 449328143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 449428143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 449528143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 449628143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 449728143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 449828143c3dSStefano Zampini } 449928143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 450028143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 450128143c3dSStefano Zampini } 450228143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 450328143c3dSStefano Zampini } 450428143c3dSStefano Zampini 4505e7931f94SStefano Zampini buf_size_idxs = 0; 4506e7931f94SStefano Zampini buf_size_vals = 0; 450728143c3dSStefano Zampini buf_size_idxs_is = 0; 4508e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4509e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4510e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 451128143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4512e7931f94SStefano Zampini } 4513785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4514785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 451595ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4516e7931f94SStefano Zampini 4517e7931f94SStefano Zampini /* get new tags for clean communications */ 4518e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4519e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 452028143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4521e7931f94SStefano Zampini 4522e7931f94SStefano Zampini /* allocate for requests */ 4523785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4524785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 452595ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4526785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4527785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 452895ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4529e7931f94SStefano Zampini 4530e7931f94SStefano Zampini /* communications */ 4531e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4532e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 453328143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4534e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4535e7931f94SStefano Zampini source_dest = onodes[i]; 4536e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4537e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4538e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4539e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 454028143c3dSStefano Zampini if (nis) { 454128143c3dSStefano 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); 454228143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 454328143c3dSStefano Zampini } 4544e7931f94SStefano Zampini } 4545e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4546e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4547e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4548e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 454928143c3dSStefano Zampini if (nis) { 455028143c3dSStefano 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); 455128143c3dSStefano Zampini } 4552e7931f94SStefano Zampini } 4553e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4554e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4555e7931f94SStefano Zampini 4556e7931f94SStefano Zampini /* assemble new l2g map */ 4557e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4558e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45599d30be91SStefano Zampini new_local_rows = 0; 4560e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45619d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4562e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4563e7931f94SStefano Zampini } 45649d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4565e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45669d30be91SStefano Zampini new_local_rows = 0; 4567e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45689d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 45699d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4570e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4571e7931f94SStefano Zampini } 45729d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 45739d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4574e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4575e7931f94SStefano Zampini 4576e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4577e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4578e7931f94SStefano 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) */ 4579e7931f94SStefano Zampini if (n_recvs) { 458028143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4581e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4582e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4583e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4584e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4585e7931f94SStefano Zampini break; 4586e7931f94SStefano Zampini } 4587e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4588e7931f94SStefano Zampini } 4589e7931f94SStefano Zampini switch (new_local_type_private) { 459028143c3dSStefano Zampini case MATDENSE_PRIVATE: 459128143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4592e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4593e7931f94SStefano Zampini bs = 1; 459428143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 459528143c3dSStefano Zampini new_local_type = MATSEQDENSE; 459628143c3dSStefano Zampini bs = 1; 459728143c3dSStefano Zampini } 4598e7931f94SStefano Zampini break; 4599e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4600e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4601e7931f94SStefano Zampini bs = 1; 4602e7931f94SStefano Zampini break; 4603e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4604e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4605e7931f94SStefano Zampini break; 4606e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4607e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4608e7931f94SStefano Zampini break; 4609e7931f94SStefano Zampini default: 46109d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4611e7931f94SStefano Zampini break; 4612e7931f94SStefano Zampini } 461328143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 461428143c3dSStefano Zampini new_local_type = MATSEQDENSE; 461528143c3dSStefano Zampini bs = 1; 4616e7931f94SStefano Zampini } 4617e7931f94SStefano Zampini 461870cf5478SStefano Zampini /* create MATIS object if needed */ 461970cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4620e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4621e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 462270cf5478SStefano Zampini } else { 462370cf5478SStefano Zampini /* it also destroys the local matrices */ 462470cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 462570cf5478SStefano Zampini } 462670cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4627e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 46289d30be91SStefano Zampini 46299d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 46309d30be91SStefano Zampini 46319d30be91SStefano Zampini /* Global to local map of received indices */ 46329d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 46339d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 46349d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 46359d30be91SStefano Zampini 46369d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 46379d30be91SStefano Zampini buf_size_idxs = 0; 46389d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 46399d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 46409d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 46419d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 46429d30be91SStefano Zampini } 46439d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 46449d30be91SStefano Zampini 46459d30be91SStefano Zampini /* set preallocation */ 46469d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 46479d30be91SStefano Zampini if (!newisdense) { 46489d30be91SStefano Zampini PetscInt *new_local_nnz=0; 46499d30be91SStefano Zampini 46509d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 46519d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 46529d30be91SStefano Zampini if (n_recvs) { 46539d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 46549d30be91SStefano Zampini } 46559d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 46569d30be91SStefano Zampini PetscInt j; 46579d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 46589d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 46599d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 46609d30be91SStefano Zampini } 46619d30be91SStefano Zampini } else { 46629d30be91SStefano Zampini /* TODO */ 46639d30be91SStefano Zampini } 46649d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 46659d30be91SStefano Zampini } 46669d30be91SStefano Zampini if (new_local_nnz) { 46679d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 46689d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 46699d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 46709d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46719d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 46729d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46739d30be91SStefano Zampini } else { 46749d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46759d30be91SStefano Zampini } 46769d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 46779d30be91SStefano Zampini } else { 46789d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46799d30be91SStefano Zampini } 4680e7931f94SStefano Zampini 4681e7931f94SStefano Zampini /* set values */ 4682e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 46839d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 4684e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4685e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 4686e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 46879d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 4688e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4689e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4690e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 469128143c3dSStefano Zampini } else { 469228143c3dSStefano Zampini /* TODO */ 4693e7931f94SStefano Zampini } 4694e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4695e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 4696e7931f94SStefano Zampini } 4697e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4698e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 469970cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 470070cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47019d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 47029d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 4703e7931f94SStefano Zampini 4704dfd14d43SStefano Zampini #if 0 470528143c3dSStefano Zampini if (!restrict_comm) { /* check */ 4706e7931f94SStefano Zampini Vec lvec,rvec; 4707e7931f94SStefano Zampini PetscReal infty_error; 4708e7931f94SStefano Zampini 47092a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 4710e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 4711e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 4712e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 471370cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 4714e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4715e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 4716e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 4717e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 4718e7931f94SStefano Zampini } 471928143c3dSStefano Zampini #endif 4720e7931f94SStefano Zampini 472128143c3dSStefano Zampini /* assemble new additional is (if any) */ 472228143c3dSStefano Zampini if (nis) { 472328143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 472428143c3dSStefano Zampini 472528143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4726854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 472728143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 472828143c3dSStefano Zampini psum = 0; 472928143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 473028143c3dSStefano Zampini for (j=0;j<nis;j++) { 473128143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 473228143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 473328143c3dSStefano Zampini psum += plen; 473428143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 473528143c3dSStefano Zampini } 473628143c3dSStefano Zampini } 4737854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 4738854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 473928143c3dSStefano Zampini for (i=1;i<nis;i++) { 474028143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 474128143c3dSStefano Zampini } 474228143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 474328143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 474428143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 474528143c3dSStefano Zampini for (j=0;j<nis;j++) { 474628143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 474728143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 474828143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 474928143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 475028143c3dSStefano Zampini } 475128143c3dSStefano Zampini } 475228143c3dSStefano Zampini for (i=0;i<nis;i++) { 475328143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 475428143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 475528143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 475628143c3dSStefano Zampini } 475728143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 475828143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 475928143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 476028143c3dSStefano Zampini } 4761e7931f94SStefano Zampini /* free workspace */ 476228143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4763e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4764e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4765e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4766e7931f94SStefano Zampini if (isdense) { 4767e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4768e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4769e7931f94SStefano Zampini } else { 4770e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4771e7931f94SStefano Zampini } 477228143c3dSStefano Zampini if (nis) { 477328143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 477428143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 477528143c3dSStefano Zampini } 4776e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4777e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 477828143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4779e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4780e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 478128143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4782e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4783e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4784e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4785e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4786e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 478728143c3dSStefano Zampini if (nis) { 478828143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 478928143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 479028143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 479128143c3dSStefano Zampini } 479228143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 479328143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 479428143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 479528143c3dSStefano Zampini for (i=0;i<nis;i++) { 479628143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 479728143c3dSStefano Zampini } 479853a05cb3SStefano Zampini *mat_n = NULL; 479928143c3dSStefano Zampini } 4800e7931f94SStefano Zampini PetscFunctionReturn(0); 4801e7931f94SStefano Zampini } 4802a57a6d2fSStefano Zampini 480312edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4804af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 480512edc857SStefano Zampini 4806c8587f34SStefano Zampini #undef __FUNCT__ 4807c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4808c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4809c8587f34SStefano Zampini { 4810c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4811c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 481220a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 48139881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 481420a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 48156e683305SStefano Zampini IS coarse_is,*isarray; 48166e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 481730368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 4818f9eb5b7dSStefano Zampini PC pc_temp; 4819c8587f34SStefano Zampini PCType coarse_pc_type; 4820c8587f34SStefano Zampini KSPType coarse_ksp_type; 4821f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 48224f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 48236e683305SStefano Zampini Mat t_coarse_mat_is; 48246e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 48256e683305SStefano Zampini PetscMPIInt all_procs; 482674e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 482768457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 482822bc73bbSStefano Zampini PetscScalar *array; 48299881197aSStefano Zampini PetscErrorCode ierr; 4830fdc09c96SStefano Zampini 4831c8587f34SStefano Zampini PetscFunctionBegin; 4832c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 483368457ee5SStefano 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 */ 4834fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 48355a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4836fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4837f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4838f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4839f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4840fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 484151bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 484251bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4843dc4bcba2SStefano Zampini PC pc; 4844dc4bcba2SStefano Zampini PetscBool isbddc; 4845dc4bcba2SStefano Zampini 4846dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4847dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4848dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4849dc4bcba2SStefano Zampini if (isbddc) { 4850dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4851dc4bcba2SStefano Zampini } 4852727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4853fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4854fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4855fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4856f4ddd8eeSStefano Zampini } 4857fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4858fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4859f4ddd8eeSStefano Zampini } 486070cf5478SStefano Zampini /* reset any subassembling information */ 486170cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 48626e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 48636e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4864fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4865f4ddd8eeSStefano Zampini } 4866c8587f34SStefano Zampini 48676e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 48682b510759SStefano Zampini im_active = !!(pcis->n); 48692b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 48706e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 48716e683305SStefano Zampini void_procs = all_procs-active_procs; 48726e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 487374e2c79eSStefano Zampini redist = PETSC_FALSE; 487422bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 48756e683305SStefano Zampini csin_ml = PETSC_TRUE; 48766e683305SStefano Zampini ncoarse_ml = void_procs; 4877779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4878779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 48796e683305SStefano Zampini csin_ds = PETSC_TRUE; 488018a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 488118a45a71SStefano Zampini redist = PETSC_TRUE; 488218a45a71SStefano Zampini } else { 48836e683305SStefano Zampini csin_ds = PETSC_TRUE; 4884779c1cceSStefano Zampini ncoarse_ds = active_procs; 4885779c1cceSStefano Zampini redist = PETSC_TRUE; 488618a45a71SStefano Zampini } 48876e683305SStefano Zampini } else { 48886e683305SStefano Zampini csin_ml = PETSC_FALSE; 48896e683305SStefano Zampini ncoarse_ml = all_procs; 48906e683305SStefano Zampini if (void_procs) { 48916e683305SStefano Zampini csin_ds = PETSC_TRUE; 48926e683305SStefano Zampini ncoarse_ds = void_procs; 48936e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 48946e683305SStefano Zampini } else { 4895779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 489674e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 489774e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 489874e2c79eSStefano Zampini redist = PETSC_TRUE; 489974e2c79eSStefano Zampini } else { 49006e683305SStefano Zampini csin_ds = PETSC_FALSE; 49016e683305SStefano Zampini ncoarse_ds = all_procs; 49026e683305SStefano Zampini } 49036e683305SStefano Zampini } 490474e2c79eSStefano Zampini } 49056e683305SStefano Zampini 49066e683305SStefano Zampini /* 49076e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 49086e683305SStefano Zampini - we have not exceeded the number of levels requested 49096e683305SStefano Zampini - we can actually subassemble the active processes 49106e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 49116e683305SStefano Zampini */ 49126e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 49136e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 49146e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 49156e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 49166e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4917f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 49182b510759SStefano Zampini } else { 4919f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4920c8587f34SStefano Zampini } 4921c8587f34SStefano Zampini } 49226e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 49236e683305SStefano Zampini if (multilevel_allowed) { 49246e683305SStefano Zampini ncoarse = ncoarse_ml; 49256e683305SStefano Zampini csin = csin_ml; 492658da7f69SStefano Zampini redist = PETSC_FALSE; 49276e683305SStefano Zampini } else { 49286e683305SStefano Zampini ncoarse = ncoarse_ds; 49296e683305SStefano Zampini csin = csin_ds; 49306e683305SStefano Zampini } 4931e7931f94SStefano Zampini 4932abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4933abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4934abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4935abbbba34SStefano Zampini 4936abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 493722bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 493822bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 493922bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 494022bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4941e176bc59SStefano 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); 49426e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 49436e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49446e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4945abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4946abbbba34SStefano Zampini 49476e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 494830368db7SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local))) { /* protects from unneded computations */ 49496e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 49506e683305SStefano Zampini const PetscInt *idxs; 49516e683305SStefano Zampini ISLocalToGlobalMapping tmap; 49526e683305SStefano Zampini 49536e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 49540be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 49556e683305SStefano Zampini /* allocate space for temporary storage */ 4956854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4957854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 49586e683305SStefano Zampini /* allocate for IS array */ 49596e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 49606e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 496130368db7SStefano Zampini nisvert = 0; 496230368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 496330368db7SStefano Zampini nisvert = 1; 496430368db7SStefano Zampini } 496530368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 4966854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 49676e683305SStefano Zampini /* dofs splitting */ 49686e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 49696e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 49706e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 49716e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49726e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49736e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49746e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 497530368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 49766e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 49776e683305SStefano Zampini } 49786e683305SStefano Zampini /* neumann boundaries */ 49796e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 49806e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 49816e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 49826e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49836e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49846e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49856e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 498630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 49876e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 49886e683305SStefano Zampini } 498930368db7SStefano Zampini /* primal vertices (benign) */ 499030368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 499130368db7SStefano Zampini ierr = ISGetLocalSize(pcbddc->user_primal_vertices_local,&tsize);CHKERRQ(ierr); 499230368db7SStefano Zampini ierr = ISGetIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 499330368db7SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 499430368db7SStefano Zampini ierr = ISRestoreIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 499530368db7SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 499630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nis-1]);CHKERRQ(ierr); 499730368db7SStefano Zampini } 49986e683305SStefano Zampini /* free memory */ 49996e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 50006e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 50016e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 50026e683305SStefano Zampini } else { 50036e683305SStefano Zampini nis = 0; 50046e683305SStefano Zampini nisdofs = 0; 50056e683305SStefano Zampini nisneu = 0; 500630368db7SStefano Zampini nisvert = 0; 50076e683305SStefano Zampini isarray = NULL; 50086e683305SStefano Zampini } 50096e683305SStefano Zampini /* destroy no longer needed map */ 50106e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 50116e683305SStefano Zampini 50126e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 50136e683305SStefano Zampini coarse_mat_is = NULL; 50146e683305SStefano Zampini if (csin) { 50156e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 501674e2c79eSStefano Zampini if (redist) { 501774e2c79eSStefano Zampini PetscMPIInt rank; 5018779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 501974e2c79eSStefano Zampini 502074e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 502158da7f69SStefano Zampini spc = active_procs/ncoarse; 502258da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 5023779c1cceSStefano Zampini if (im_active) { 5024779c1cceSStefano Zampini destsize = 1; 502574e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 502674e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 502774e2c79eSStefano Zampini } else { 502874e2c79eSStefano Zampini dest[0] = rank/(spc+1); 502974e2c79eSStefano Zampini } 503074e2c79eSStefano Zampini } else { 5031779c1cceSStefano Zampini destsize = 0; 50326e683305SStefano Zampini } 5033779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5034779c1cceSStefano Zampini } else if (csin_type_simple) { 50356e683305SStefano Zampini PetscMPIInt rank; 50366e683305SStefano Zampini PetscInt issize,isidx; 5037779c1cceSStefano Zampini 50386e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 50396e683305SStefano Zampini if (im_active) { 50406e683305SStefano Zampini issize = 1; 50416e683305SStefano Zampini isidx = (PetscInt)rank; 50426e683305SStefano Zampini } else { 50436e683305SStefano Zampini issize = 0; 50446e683305SStefano Zampini isidx = -1; 50456e683305SStefano Zampini } 50466e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5047779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 5048b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 50496e683305SStefano Zampini } 5050779c1cceSStefano Zampini 5051779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 5052779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 5053779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 5054779c1cceSStefano Zampini PetscInt *coarse_candidates; 5055779c1cceSStefano Zampini const PetscInt* tisindices; 5056779c1cceSStefano Zampini 5057779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 5058779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 5059779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5060779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 5061779c1cceSStefano Zampini if (!coarse_candidates[i]) { 5062779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 5063779c1cceSStefano Zampini } 5064779c1cceSStefano Zampini } 5065779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 5066779c1cceSStefano Zampini 5067779c1cceSStefano Zampini 50686e683305SStefano Zampini if (pcbddc->dbg_flag) { 50696e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50706e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 50716e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50726e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 5073779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 50746e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 50756e683305SStefano Zampini } 50766e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 50776e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50786e683305SStefano Zampini } 50796e683305SStefano Zampini /* shift the pattern on coarse candidates */ 50806e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 50816e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 5082854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 50836e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 50846e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 50856e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 50866e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 50876e683305SStefano Zampini } 50886e683305SStefano Zampini if (pcbddc->dbg_flag) { 50896e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50906e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 50916e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50926e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50936e683305SStefano Zampini } 5094779c1cceSStefano Zampini } 50956e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 509653a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 509753a05cb3SStefano 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); 509853a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 509953a05cb3SStefano 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); 510053a05cb3SStefano Zampini } 51016e683305SStefano Zampini } else { 51026e683305SStefano Zampini if (pcbddc->dbg_flag) { 51036e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 51046e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 51056e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 51066e683305SStefano Zampini } 51076e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 51086e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 51096e683305SStefano Zampini } 51106e683305SStefano Zampini 51116e683305SStefano Zampini /* create local to global scatters for coarse problem */ 511268457ee5SStefano Zampini if (compute_vecs) { 51136e683305SStefano Zampini PetscInt lrows; 51146e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 51156e683305SStefano Zampini if (coarse_mat_is) { 51166e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 51176e683305SStefano Zampini } else { 51186e683305SStefano Zampini lrows = 0; 51196e683305SStefano Zampini } 51206e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 51216e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 51226e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 51236e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 51246e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 51256e683305SStefano Zampini } 51266e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 51276e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 5128c8587f34SStefano Zampini 5129f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5130f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5131f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5132f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5133f9eb5b7dSStefano Zampini } else { 5134f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5135f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5136c8587f34SStefano Zampini } 5137c8587f34SStefano Zampini 51386e683305SStefano Zampini /* print some info if requested */ 51396e683305SStefano Zampini if (pcbddc->dbg_flag) { 51406e683305SStefano Zampini if (!multilevel_allowed) { 51416e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 51426e683305SStefano Zampini if (multilevel_requested) { 51436e683305SStefano 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); 51446e683305SStefano Zampini } else if (pcbddc->max_levels) { 51456e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 51466e683305SStefano Zampini } 51476e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 51486e683305SStefano Zampini } 51496e683305SStefano Zampini } 51506e683305SStefano Zampini 5151f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 51526e683305SStefano Zampini if (coarse_mat_is) { 51536e683305SStefano Zampini MatReuse coarse_mat_reuse; 51546a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 51556e683305SStefano Zampini if (pcbddc->dbg_flag) { 51566e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 51576e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 51586e683305SStefano Zampini } 5159f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5160312be037SStefano Zampini char prefix[256],str_level[16]; 5161e604994aSStefano Zampini size_t len; 51626e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5163422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5164c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5165f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 51665f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 5167c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 51686e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5169c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5170c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5171e604994aSStefano Zampini /* prefix */ 5172e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5173e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5174e604994aSStefano Zampini if (!pcbddc->current_level) { 5175e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5176e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5177c8587f34SStefano Zampini } else { 5178e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5179312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5180312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 518134d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5182312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5183e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5184e604994aSStefano Zampini } 5185e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 51863e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 51873e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 51883e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 51893e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5190f9eb5b7dSStefano Zampini /* allow user customization */ 5191f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 51923e3c6dadSStefano Zampini } 51933e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 519451bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 51953e3c6dadSStefano Zampini if (nisdofs) { 51963e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 51973e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 51983e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 51993e3c6dadSStefano Zampini } 52003e3c6dadSStefano Zampini } 52013e3c6dadSStefano Zampini if (nisneu) { 52023e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 52033e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5204312be037SStefano Zampini } 520530368db7SStefano Zampini if (nisvert) { 520630368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 520730368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 520830368db7SStefano Zampini } 5209f9eb5b7dSStefano Zampini 5210f9eb5b7dSStefano Zampini /* get some info after set from options */ 5211f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5212f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 52134f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 52146e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5215f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5216f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5217f9eb5b7dSStefano Zampini } 521839f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 52194f3a063dSStefano Zampini if (isredundant) { 52204f3a063dSStefano Zampini KSP inner_ksp; 52214f3a063dSStefano Zampini PC inner_pc; 52224f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 52234f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 52244f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 52254f3a063dSStefano Zampini } 5226f9eb5b7dSStefano Zampini 5227f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 5228fa7f1dd8SStefano Zampini if (coarse_reuse) { 522981d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 5230fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 52316e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 5232fa7f1dd8SStefano Zampini } else { 52336e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 5234fa7f1dd8SStefano Zampini } 5235c8587f34SStefano Zampini if (isbddc || isnn) { 523622bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 523770cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 5238b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 523922b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 52406e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 52416e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 52426e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 52436e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 524422b6e8a2SStefano Zampini } 524570cf5478SStefano Zampini } 524653a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 524770cf5478SStefano Zampini } else { 524822bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 524922bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 525022bc73bbSStefano Zampini } 525122bc73bbSStefano Zampini } else { 52522e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 5253c8587f34SStefano Zampini } 5254c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 5255c8587f34SStefano Zampini 52563301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 52575a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 52583301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 52593301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 52603301b35fSStefano Zampini } 52613301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 52623301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 52633301b35fSStefano Zampini } 52643301b35fSStefano Zampini if (pc->pmat->spd_set) { 52653301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 52663301b35fSStefano Zampini } 52676e683305SStefano Zampini /* set operators */ 52685f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 52696e683305SStefano Zampini if (pcbddc->dbg_flag) { 52706e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 52716e683305SStefano Zampini } 52726e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 52736e683305SStefano Zampini coarse_mat = 0; 52746e683305SStefano Zampini } 52756e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5276b1ecc7b1SStefano Zampini #if 0 5277b9b85e73SStefano Zampini { 5278b9b85e73SStefano Zampini PetscViewer viewer; 5279b9b85e73SStefano Zampini char filename[256]; 5280b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5281b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 5282b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5283b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5284b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5285b9b85e73SStefano Zampini } 5286b9b85e73SStefano Zampini #endif 5287c8587f34SStefano Zampini 5288c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 5289298c0119SStefano Zampini #if 0 5290c8587f34SStefano Zampini if (pcbddc->NullSpace) { 5291c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 529298a51de6SStefano Zampini } 5293298c0119SStefano Zampini #endif 5294b0f5fe93SStefano Zampini /* hack */ 529598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 529698a51de6SStefano Zampini Vec crhs,csol; 529704708bb6SStefano Zampini 5298f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 5299f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 5300f347579bSStefano Zampini if (!csol) { 53012a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 5302f9eb5b7dSStefano Zampini } 5303f347579bSStefano Zampini if (!crhs) { 53042a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 5305f347579bSStefano Zampini } 5306b0f5fe93SStefano Zampini } 5307b0f5fe93SStefano Zampini 5308b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 5309b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 5310b0f5fe93SStefano Zampini 5311b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 53124f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 53134f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 53144f1b2e48SStefano Zampini } 5315b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 5316b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 5317b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5318b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5319b0f5fe93SStefano Zampini if (coarse_mat) { 5320b0f5fe93SStefano Zampini Vec nullv; 5321b0f5fe93SStefano Zampini PetscScalar *array,*array2; 5322b0f5fe93SStefano Zampini PetscInt nl; 5323b0f5fe93SStefano Zampini 5324b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 5325b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 5326b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5327b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 5328b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 5329b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 5330b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5331b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 5332b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 5333b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 5334b0f5fe93SStefano Zampini } 5335b0f5fe93SStefano Zampini } 5336b0f5fe93SStefano Zampini 5337b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 5338b0f5fe93SStefano Zampini PetscBool ispreonly; 5339b0f5fe93SStefano Zampini 5340b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5341b0f5fe93SStefano Zampini PetscBool isnull; 5342b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 5343b0f5fe93SStefano Zampini if (isnull) { 534430368db7SStefano Zampini if (isbddc && !pcbddc->benign_saddle_point) { 5345b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 5346b0f5fe93SStefano Zampini } else { 5347b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 5348b0f5fe93SStefano Zampini } 5349b0f5fe93SStefano Zampini } else { 5350b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5351b0f5fe93SStefano Zampini } 5352b0f5fe93SStefano Zampini } 5353b0f5fe93SStefano Zampini /* setup coarse ksp */ 5354b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 5355cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 5356cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 53576e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 5358c8587f34SStefano Zampini KSP check_ksp; 53592b510759SStefano Zampini KSPType check_ksp_type; 5360c8587f34SStefano Zampini PC check_pc; 53616e683305SStefano Zampini Vec check_vec,coarse_vec; 53626a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 53632b510759SStefano Zampini PetscInt its; 53646e683305SStefano Zampini PetscBool compute_eigs; 53656e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 53666e683305SStefano Zampini PetscInt neigs; 53678e185a42SStefano Zampini const char *prefix; 5368c8587f34SStefano Zampini 53692b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 53706e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 5371422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 537223ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5373f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 53742b510759SStefano Zampini if (ispreonly) { 53752b510759SStefano Zampini check_ksp_type = KSPPREONLY; 53766e683305SStefano Zampini compute_eigs = PETSC_FALSE; 53772b510759SStefano Zampini } else { 5378cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 53796e683305SStefano Zampini compute_eigs = PETSC_TRUE; 5380c8587f34SStefano Zampini } 5381c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 53826e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 53836e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 53846e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5385a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5386a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5387a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5388a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5389c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5390c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5391c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5392c8587f34SStefano Zampini /* create random vec */ 53936e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 53946e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5395c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5396c8587f34SStefano Zampini if (CoarseNullSpace) { 5397c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5398c8587f34SStefano Zampini } 53996e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5400c8587f34SStefano Zampini /* solve coarse problem */ 54016e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5402c8587f34SStefano Zampini if (CoarseNullSpace) { 54036e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5404c8587f34SStefano Zampini } 5405cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 54066e683305SStefano Zampini if (compute_eigs) { 5407854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5408854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 54096e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 54106e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 54116e683305SStefano Zampini lambda_min = eigs_r[0]; 54126e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 54136e683305SStefano Zampini if (lambda_max>lambda_min) { 5414cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5415cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5416cbcc2c2aSStefano Zampini } 5417c8587f34SStefano Zampini } 5418c8587f34SStefano Zampini } 5419cbcc2c2aSStefano Zampini 5420c8587f34SStefano Zampini /* check coarse problem residual error */ 54216e683305SStefano Zampini if (pcbddc->dbg_flag) { 54226e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 54236e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 54246e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5425c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 54266e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 54276e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5428c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5429779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 54306e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 54316e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 54326e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 54336e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5434b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5435b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5436b0f5fe93SStefano Zampini } 54376e683305SStefano Zampini if (compute_eigs) { 54386e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5439deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5440c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 54416e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 54426e683305SStefano 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); 54436e683305SStefano Zampini for (i=0;i<neigs;i++) { 54446e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5445c8587f34SStefano Zampini } 54466e683305SStefano Zampini } 54476e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 54486e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 54496e683305SStefano Zampini } 5450c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 54516e683305SStefano Zampini if (compute_eigs) { 54526e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 54536e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5454c8587f34SStefano Zampini } 54556e683305SStefano Zampini } 54566e683305SStefano Zampini } 5457cbcc2c2aSStefano Zampini /* print additional info */ 5458cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 54596e683305SStefano Zampini /* waits until all processes reaches this point */ 54606e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5461cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5462cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5463cbcc2c2aSStefano Zampini } 5464cbcc2c2aSStefano Zampini 54652b510759SStefano Zampini /* free memory */ 5466c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5467fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5468c8587f34SStefano Zampini PetscFunctionReturn(0); 5469c8587f34SStefano Zampini } 5470674ae819SStefano Zampini 5471f34684f1SStefano Zampini #undef __FUNCT__ 5472f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5473f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5474f34684f1SStefano Zampini { 5475f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5476f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5477f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5478dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5479dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 548073be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5481dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5482f34684f1SStefano Zampini PetscErrorCode ierr; 5483f34684f1SStefano Zampini 5484f34684f1SStefano Zampini PetscFunctionBegin; 5485f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 54860e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 54870e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5488727cdba6SStefano Zampini } 5489dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 54903bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5491dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5492dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5493dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5494dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5495dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5496dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 54970e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 54980e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 54990e6343abSStefano Zampini } 5500dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5501dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5502dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5503dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5504dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5505f34684f1SStefano Zampini 5506f34684f1SStefano Zampini /* check numbering */ 5507f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5508019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5509dc456d91SStefano Zampini PetscInt i; 5510b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5511f34684f1SStefano Zampini 5512f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5513f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5514f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 55150fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 5516019a44ceSStefano Zampini /* counter */ 5517019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5518019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5519019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5520019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5521019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5522019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5523019a44ceSStefano Zampini 5524f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5525f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5526727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5527f34684f1SStefano Zampini } 5528f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5529f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5530f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5531e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5532e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5533e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5534e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5535f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5536019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5537f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5538019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 553975c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 554075c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5541b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5542019a44ceSStefano 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); 5543f34684f1SStefano Zampini } 5544f34684f1SStefano Zampini } 5545019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5546b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5547f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5548f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5549f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5550f34684f1SStefano Zampini } 5551f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5552f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5553e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5554e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5555f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5556f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5557b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5558ca8b9ea9SStefano Zampini PetscInt *gidxs; 5559ca8b9ea9SStefano Zampini 5560ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 55613bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5562f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5563f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5564f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5565f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 55664bc2dc4bSStefano 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); 5567f34684f1SStefano Zampini } 5568f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5569ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5570f34684f1SStefano Zampini } 5571f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5572302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5573f34684f1SStefano Zampini } 55748bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5575f34684f1SStefano Zampini /* get back data */ 5576f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5577f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5578674ae819SStefano Zampini PetscFunctionReturn(0); 5579674ae819SStefano Zampini } 5580674ae819SStefano Zampini 5581e456f2a8SStefano Zampini #undef __FUNCT__ 5582e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5583a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5584e456f2a8SStefano Zampini { 5585e456f2a8SStefano Zampini IS localis_t; 5586a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5587e456f2a8SStefano Zampini PetscScalar *vals; 5588e456f2a8SStefano Zampini PetscErrorCode ierr; 5589e456f2a8SStefano Zampini 5590e456f2a8SStefano Zampini PetscFunctionBegin; 5591a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5592e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5593854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5594e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5595e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5596a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5597a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 55981035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5599a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 56001035eff8SStefano Zampini } 5601a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5602e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5603e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5604a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5605a7dc3881SStefano Zampini /* now compute set in local ordering */ 5606a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5607a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5608a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5609a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5610a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5611ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5612e456f2a8SStefano Zampini lsize++; 5613e456f2a8SStefano Zampini } 5614e456f2a8SStefano Zampini } 5615854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5616a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5617ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5618e456f2a8SStefano Zampini idxs[lsize++] = i; 5619e456f2a8SStefano Zampini } 5620e456f2a8SStefano Zampini } 5621a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5622a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5623e456f2a8SStefano Zampini *localis = localis_t; 5624e456f2a8SStefano Zampini PetscFunctionReturn(0); 5625e456f2a8SStefano Zampini } 5626906d46d4SStefano Zampini 5627906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5628906d46d4SStefano Zampini #undef __FUNCT__ 5629906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5630906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5631906d46d4SStefano Zampini { 5632906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5633906d46d4SStefano Zampini PetscErrorCode ierr; 5634906d46d4SStefano Zampini 5635906d46d4SStefano Zampini PetscFunctionBegin; 5636906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5637906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5638906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5639906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5640906d46d4SStefano Zampini PetscFunctionReturn(0); 5641906d46d4SStefano Zampini } 5642906d46d4SStefano Zampini 5643906d46d4SStefano Zampini #undef __FUNCT__ 5644906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5645906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5646906d46d4SStefano Zampini { 5647906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5648906d46d4SStefano Zampini PetscErrorCode ierr; 5649906d46d4SStefano Zampini 5650906d46d4SStefano Zampini PetscFunctionBegin; 5651906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5652906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5653906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5654906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5655906d46d4SStefano Zampini PetscFunctionReturn(0); 5656906d46d4SStefano Zampini } 5657b96c3477SStefano Zampini 5658b96c3477SStefano Zampini #undef __FUNCT__ 5659b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 566008122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5661b96c3477SStefano Zampini { 5662a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5663b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5664b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5665a64f4aa4SStefano Zampini Mat S_j; 5666b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 5667b96c3477SStefano Zampini PetscBool free_used_adj; 5668b96c3477SStefano Zampini PetscErrorCode ierr; 5669b96c3477SStefano Zampini 5670b96c3477SStefano Zampini PetscFunctionBegin; 5671b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 5672b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 567308122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 5674b96c3477SStefano Zampini used_xadj = NULL; 5675b96c3477SStefano Zampini used_adjncy = NULL; 5676b96c3477SStefano Zampini } else { 567708122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 567808122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 567908122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 568008122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 5681b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 5682b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 5683b96c3477SStefano Zampini } else { 56842fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 5685b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 5686b96c3477SStefano Zampini PetscInt nvtxs; 5687b96c3477SStefano Zampini 56882fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 56892fffb893SStefano Zampini if (flg_row) { 5690b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 5691b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 5692b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 5693b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 56942fffb893SStefano Zampini } else { 56952fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 56962fffb893SStefano Zampini used_xadj = NULL; 56972fffb893SStefano Zampini used_adjncy = NULL; 56982fffb893SStefano Zampini } 56992fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 5700b96c3477SStefano Zampini } 5701b96c3477SStefano Zampini } 5702d5574798SStefano Zampini 5703d5574798SStefano Zampini /* setup sub_schurs data */ 5704a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5705a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 5706a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 5707a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 570806a4e24aSStefano 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); 5709a64f4aa4SStefano Zampini } else { 57106816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 571104708bb6SStefano Zampini PetscBool isseqaij; 57125feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 57135feab87aSStefano Zampini PetscInt n_vertices; 57145feab87aSStefano Zampini 57155feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 57162034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 57175feab87aSStefano Zampini } 571804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 571904708bb6SStefano Zampini if (!isseqaij) { 572004708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 572104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 572204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 572304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 572404708bb6SStefano Zampini } else { 572504708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 572604708bb6SStefano Zampini } 572704708bb6SStefano Zampini } 572806a4e24aSStefano 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); 5729a64f4aa4SStefano Zampini } 5730a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5731b96c3477SStefano Zampini 5732b96c3477SStefano Zampini /* free adjacency */ 5733b96c3477SStefano Zampini if (free_used_adj) { 5734b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 5735b96c3477SStefano Zampini } 5736b96c3477SStefano Zampini PetscFunctionReturn(0); 5737b96c3477SStefano Zampini } 5738b96c3477SStefano Zampini 5739b96c3477SStefano Zampini #undef __FUNCT__ 5740b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 574108122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 5742b96c3477SStefano Zampini { 5743b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5744b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5745b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5746b96c3477SStefano Zampini PCBDDCGraph graph; 5747b96c3477SStefano Zampini PetscErrorCode ierr; 5748b96c3477SStefano Zampini 5749b96c3477SStefano Zampini PetscFunctionBegin; 5750b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 575108122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 57523301b35fSStefano Zampini IS verticesIS,verticescomm; 57533301b35fSStefano Zampini PetscInt vsize,*idxs; 5754b96c3477SStefano Zampini 5755b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 57563301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 57573301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57583301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 57593301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57603301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 5761b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 57627fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 57633301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 57643301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 5765b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5766b96c3477SStefano Zampini /* 5767b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 5768b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5769b96c3477SStefano Zampini } 5770b96c3477SStefano Zampini */ 5771b96c3477SStefano Zampini } else { 5772b96c3477SStefano Zampini graph = pcbddc->mat_graph; 5773b96c3477SStefano Zampini } 5774b96c3477SStefano Zampini 5775b96c3477SStefano Zampini /* sub_schurs init */ 5776a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 5777a64f4aa4SStefano Zampini 5778b96c3477SStefano Zampini /* free graph struct */ 577908122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 5780b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 5781b96c3477SStefano Zampini } 5782b96c3477SStefano Zampini PetscFunctionReturn(0); 5783b96c3477SStefano Zampini } 5784fa34dd3eSStefano Zampini 5785fa34dd3eSStefano Zampini #undef __FUNCT__ 5786fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 5787fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 5788fa34dd3eSStefano Zampini { 5789fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5790fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5791fa34dd3eSStefano Zampini PetscErrorCode ierr; 5792fa34dd3eSStefano Zampini 5793fa34dd3eSStefano Zampini PetscFunctionBegin; 5794fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 5795fa34dd3eSStefano Zampini IS zerodiag = NULL; 57964f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 5797fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 57984f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 579975c01103SStefano Zampini PetscReal norm; 5800fa34dd3eSStefano Zampini PetscInt i; 5801fa34dd3eSStefano Zampini 5802fa34dd3eSStefano Zampini /* B0 and B0_B */ 5803fa34dd3eSStefano Zampini if (zerodiag) { 5804fa34dd3eSStefano Zampini IS dummy; 5805fa34dd3eSStefano Zampini 58064f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 58074f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 5808fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 5809fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 5810fa34dd3eSStefano Zampini } 5811fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 5812fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 5813fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 5814fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5815fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5816fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5817fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5818fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 5819fa34dd3eSStefano Zampini /* S_j */ 5820fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5821fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 5822fa34dd3eSStefano Zampini 5823fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 5824fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 5825fa34dd3eSStefano Zampini /* continuous in primal space */ 5826fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 5827fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5828fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5829fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 58304f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 58314f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 5832fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5833fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5834fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5835fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5836fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5837fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5838fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 5839fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 5840fa34dd3eSStefano Zampini 5841fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 5842fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 5843fa34dd3eSStefano Zampini /* local with Schur */ 5844fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 5845fa34dd3eSStefano Zampini if (zerodiag) { 5846fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 58474f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 5848fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5849fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5850fa34dd3eSStefano Zampini } 5851fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 5852fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5853fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5854fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5855fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5856fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 5857fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5858fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5859fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 5860fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5861fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5862fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5863fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5864fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5865fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 5866fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 5867fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5868fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5869fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5870fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5871fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5872fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5873fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 5874fa34dd3eSStefano Zampini if (zerodiag) { 5875fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 5876fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 58774f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 5878fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5879fa34dd3eSStefano Zampini } 5880fa34dd3eSStefano Zampini /* BDDC */ 5881fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 5882fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 5883fa34dd3eSStefano Zampini 5884fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 5885fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 5886fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 5887fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 58884f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 58894f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 5890fa34dd3eSStefano Zampini } 58914f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 5892fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 5893fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 5894fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 5895fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5896fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 5897fa34dd3eSStefano Zampini } 5898fa34dd3eSStefano Zampini PetscFunctionReturn(0); 5899fa34dd3eSStefano Zampini } 5900