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> 5daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 6674ae819SStefano Zampini 7669cc0f4SStefano Zampini 8669cc0f4SStefano Zampini #undef __FUNCT__ 9669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 10*fa23a32eSStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 11669cc0f4SStefano Zampini { 12a198735bSStefano Zampini Mat loc_divudotp; 13*fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 14669cc0f4SStefano Zampini ISLocalToGlobalMapping rmap; 15669cc0f4SStefano Zampini IS *faces,*edges; 16669cc0f4SStefano Zampini PetscScalar *vals; 17669cc0f4SStefano Zampini const PetscScalar *array; 18669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 191ae86dd6SStefano Zampini PetscMPIInt rank; 20a198735bSStefano Zampini PetscErrorCode ierr; 21669cc0f4SStefano Zampini 22669cc0f4SStefano Zampini PetscFunctionBegin; 23669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 24669cc0f4SStefano Zampini if (graph->twodim) { 25669cc0f4SStefano Zampini lmaxneighs = 2; 26669cc0f4SStefano Zampini } else { 27669cc0f4SStefano Zampini lmaxneighs = 1; 28669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 29669cc0f4SStefano Zampini const PetscInt *idxs; 30669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 31669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 32669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 33669cc0f4SStefano Zampini } 34669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 35669cc0f4SStefano Zampini } 36669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 37669cc0f4SStefano Zampini maxsize = 0; 38669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 39669cc0f4SStefano Zampini PetscInt nn; 40669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 41669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 42669cc0f4SStefano Zampini } 43669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 44669cc0f4SStefano Zampini PetscInt nn; 45669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 46669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 47669cc0f4SStefano Zampini } 48669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 49669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 50669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 51669cc0f4SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rmap,NULL);CHKERRQ(ierr); 52669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 531ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 54669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 55669cc0f4SStefano Zampini PetscInt first,last; 56669cc0f4SStefano Zampini 57669cc0f4SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],rmap);CHKERRQ(ierr); 58669cc0f4SStefano Zampini /* the near-null space fo BDDC carries information on quadrature weights, 59669cc0f4SStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 60669cc0f4SStefano Zampini and create a suitable set of basis vectors first */ 61669cc0f4SStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 62669cc0f4SStefano Zampini if (i>=first && i < last) { 63669cc0f4SStefano Zampini PetscScalar *data; 64669cc0f4SStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 65669cc0f4SStefano Zampini data[i-first] = 1.; 66669cc0f4SStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 67669cc0f4SStefano Zampini } 68669cc0f4SStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 69669cc0f4SStefano Zampini } 70669cc0f4SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 711ae86dd6SStefano Zampini for (i=0;i<maxneighs;i++) { /* reset vectors */ 721ae86dd6SStefano Zampini PetscInt first,last; 731ae86dd6SStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 741ae86dd6SStefano Zampini if (i>=first && i < last) { 751ae86dd6SStefano Zampini PetscScalar *data; 761ae86dd6SStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 771ae86dd6SStefano Zampini data[i-first] = 0.; 781ae86dd6SStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 791ae86dd6SStefano Zampini } 801ae86dd6SStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 811ae86dd6SStefano Zampini } 82669cc0f4SStefano Zampini /* compute local quad vec */ 83a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 84a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 85669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 86a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 87*fa23a32eSStefano Zampini if (vl2l) { 88*fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 89*fa23a32eSStefano Zampini } else { 90*fa23a32eSStefano Zampini vins = v; 91*fa23a32eSStefano Zampini } 92*fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 93669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 941ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 951ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 96669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 97669cc0f4SStefano Zampini const PetscInt *idxs; 98669cc0f4SStefano Zampini PetscInt idx,nn,j; 99669cc0f4SStefano Zampini 100669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 101669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 102669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 1031ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 104669cc0f4SStefano Zampini idx = -(idx+1); 105669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 106669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 107669cc0f4SStefano Zampini ierr = ISDestroy(&faces[i]);CHKERRQ(ierr); 108669cc0f4SStefano Zampini } 109669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 110669cc0f4SStefano Zampini const PetscInt *idxs; 111669cc0f4SStefano Zampini PetscInt idx,nn,j; 112669cc0f4SStefano Zampini 113669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 114669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 115669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 1161ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 117669cc0f4SStefano Zampini idx = -(idx+1); 118669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 119669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 120669cc0f4SStefano Zampini ierr = ISDestroy(&edges[i]);CHKERRQ(ierr); 121669cc0f4SStefano Zampini } 122669cc0f4SStefano Zampini ierr = PetscFree(edges);CHKERRQ(ierr); 123669cc0f4SStefano Zampini ierr = PetscFree(faces);CHKERRQ(ierr); 124*fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 125*fa23a32eSStefano Zampini if (vl2l) { 126*fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 127*fa23a32eSStefano Zampini } 128669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 129669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 130669cc0f4SStefano Zampini 131669cc0f4SStefano Zampini /* assemble near null space */ 132669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 133669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 134669cc0f4SStefano Zampini } 135669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 136669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 137669cc0f4SStefano Zampini } 138669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 139669cc0f4SStefano Zampini PetscFunctionReturn(0); 140669cc0f4SStefano Zampini } 141669cc0f4SStefano Zampini 142669cc0f4SStefano Zampini 143a3df083aSStefano Zampini #undef __FUNCT__ 1441f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 1451f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 1461f4df5f7SStefano Zampini { 1471f4df5f7SStefano Zampini PetscErrorCode ierr; 1481f4df5f7SStefano Zampini Vec local,global; 1491f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1501f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1511f4df5f7SStefano Zampini 1521f4df5f7SStefano Zampini PetscFunctionBegin; 1531f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 1541f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 1551f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 1561f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 1571f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 1581f4df5f7SStefano Zampini PetscInt i; 1591f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1601f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 1611f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 1621f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 1631f4df5f7SStefano Zampini } 1641f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 1651f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 1661f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 1671f4df5f7SStefano Zampini } 1681f4df5f7SStefano Zampini } else { 169986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 1701f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 171986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 172986cdee1SStefano Zampini if (i > 1) { 173986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 1741f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1751f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 1761f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 1771f4df5f7SStefano Zampini } 1781f4df5f7SStefano Zampini } 1791f4df5f7SStefano Zampini } 180986cdee1SStefano Zampini } 1811f4df5f7SStefano Zampini 1821f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 1831f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 1841f4df5f7SStefano Zampini } 1851f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 1861f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1871f4df5f7SStefano Zampini } 1881f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 1891f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1901f4df5f7SStefano Zampini } 1911f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 1921f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 1931f4df5f7SStefano Zampini PetscFunctionReturn(0); 1941f4df5f7SStefano Zampini } 1951f4df5f7SStefano Zampini 1961f4df5f7SStefano Zampini #undef __FUNCT__ 1973e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 1983e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 1993e589ea0SStefano Zampini { 2003e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 2013e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2023e589ea0SStefano Zampini PetscErrorCode ierr; 2033e589ea0SStefano Zampini 2043e589ea0SStefano Zampini PetscFunctionBegin; 2053e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 2063e589ea0SStefano Zampini PetscFunctionReturn(0); 2073e589ea0SStefano Zampini } 2083e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2093e589ea0SStefano Zampini Vec swap; 2103e589ea0SStefano Zampini 2113e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 2123e589ea0SStefano Zampini swap = pcbddc->work_change; 2133e589ea0SStefano Zampini pcbddc->work_change = r; 2143e589ea0SStefano Zampini r = swap; 2153e589ea0SStefano Zampini } 2163e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2173e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2183e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 2193e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 2203e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2213e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2223e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2233e589ea0SStefano Zampini Vec swap; 2243e589ea0SStefano Zampini 2253e589ea0SStefano Zampini swap = r; 2263e589ea0SStefano Zampini r = pcbddc->work_change; 2273e589ea0SStefano Zampini pcbddc->work_change = swap; 2283e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 2293e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 2303e589ea0SStefano Zampini } 2313e589ea0SStefano Zampini PetscFunctionReturn(0); 2323e589ea0SStefano Zampini } 2333e589ea0SStefano Zampini 2343e589ea0SStefano Zampini #undef __FUNCT__ 235a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 236a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 237a3df083aSStefano Zampini { 238a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 239a3df083aSStefano Zampini PetscErrorCode ierr; 240a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 241a3df083aSStefano Zampini 242a3df083aSStefano Zampini PetscFunctionBegin; 243a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 244a3df083aSStefano Zampini if (transpose) { 245a3df083aSStefano Zampini apply_right = ctx->apply_left; 246a3df083aSStefano Zampini apply_left = ctx->apply_right; 247a3df083aSStefano Zampini } else { 248a3df083aSStefano Zampini apply_right = ctx->apply_right; 249a3df083aSStefano Zampini apply_left = ctx->apply_left; 250a3df083aSStefano Zampini } 251a3df083aSStefano Zampini reset_x = PETSC_FALSE; 252a3df083aSStefano Zampini if (apply_right) { 253a3df083aSStefano Zampini const PetscScalar *ax; 254a3df083aSStefano Zampini PetscInt nl,i; 255a3df083aSStefano Zampini 256a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 257a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 258a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 259a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 260a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 261a3df083aSStefano Zampini PetscScalar sum,val; 262a3df083aSStefano Zampini const PetscInt *idxs; 263a3df083aSStefano Zampini PetscInt nz,j; 264a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 265a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 266a3df083aSStefano Zampini sum = 0.; 267a3df083aSStefano Zampini if (ctx->apply_p0) { 268a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 269a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 270a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 271a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 272a3df083aSStefano Zampini } 273a3df083aSStefano Zampini } else { 274a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 275a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 276a3df083aSStefano Zampini } 277a3df083aSStefano Zampini } 278a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 279a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 280a3df083aSStefano Zampini } 281a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 282a3df083aSStefano Zampini reset_x = PETSC_TRUE; 283a3df083aSStefano Zampini } 284a3df083aSStefano Zampini if (transpose) { 285a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 286a3df083aSStefano Zampini } else { 287a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 288a3df083aSStefano Zampini } 289a3df083aSStefano Zampini if (reset_x) { 290a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 291a3df083aSStefano Zampini } 292a3df083aSStefano Zampini if (apply_left) { 293a3df083aSStefano Zampini PetscScalar *ay; 294a3df083aSStefano Zampini PetscInt i; 295a3df083aSStefano Zampini 296a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 297a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 298a3df083aSStefano Zampini PetscScalar sum,val; 299a3df083aSStefano Zampini const PetscInt *idxs; 300a3df083aSStefano Zampini PetscInt nz,j; 301a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 302a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 303a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 304a3df083aSStefano Zampini if (ctx->apply_p0) { 305a3df083aSStefano Zampini sum = 0.; 306a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 307a3df083aSStefano Zampini sum += ay[idxs[j]]; 308a3df083aSStefano Zampini ay[idxs[j]] += val; 309a3df083aSStefano Zampini } 310a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 311a3df083aSStefano Zampini } else { 312a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 313a3df083aSStefano Zampini ay[idxs[j]] += val; 314a3df083aSStefano Zampini } 315a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 316a3df083aSStefano Zampini } 317a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 318a3df083aSStefano Zampini } 319a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 320a3df083aSStefano Zampini } 321a3df083aSStefano Zampini PetscFunctionReturn(0); 322a3df083aSStefano Zampini } 323a3df083aSStefano Zampini 324a3df083aSStefano Zampini #undef __FUNCT__ 325a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 326a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 327a3df083aSStefano Zampini { 328a3df083aSStefano Zampini PetscErrorCode ierr; 329a3df083aSStefano Zampini 330a3df083aSStefano Zampini PetscFunctionBegin; 331a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 332a3df083aSStefano Zampini PetscFunctionReturn(0); 333a3df083aSStefano Zampini } 334a3df083aSStefano Zampini 335a3df083aSStefano Zampini #undef __FUNCT__ 336a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 337a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 338a3df083aSStefano Zampini { 339a3df083aSStefano Zampini PetscErrorCode ierr; 340a3df083aSStefano Zampini 341a3df083aSStefano Zampini PetscFunctionBegin; 342a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 343a3df083aSStefano Zampini PetscFunctionReturn(0); 344a3df083aSStefano Zampini } 345a3df083aSStefano Zampini 346a3df083aSStefano Zampini #undef __FUNCT__ 347a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 348a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 349a3df083aSStefano Zampini { 350a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 351a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 352a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 353a3df083aSStefano Zampini PetscErrorCode ierr; 354a3df083aSStefano Zampini 355a3df083aSStefano Zampini PetscFunctionBegin; 356a3df083aSStefano Zampini if (!restore) { 3571dd7afcfSStefano Zampini Mat A_IB,A_BI; 358a3df083aSStefano Zampini PetscScalar *work; 359b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 360a3df083aSStefano Zampini 3611dd7afcfSStefano Zampini if (pcbddc->benign_original_mat) { 3621dd7afcfSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 3631dd7afcfSStefano Zampini } 3641dd7afcfSStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) { 3651dd7afcfSStefano Zampini PetscFunctionReturn(0); 3661dd7afcfSStefano Zampini } 367a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 368a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 369a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 370a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 371a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 372a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 373a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 374a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 375a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 376a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 377a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 378a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 379059032f7SStefano Zampini if (reuse) { 380a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 3811dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 382059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 383059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 384059032f7SStefano Zampini PetscInt i; 385059032f7SStefano Zampini 386059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 387059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 388059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 389059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 390059032f7SStefano Zampini } 391059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 3921dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 393059032f7SStefano Zampini } 394a3df083aSStefano Zampini ctx->A = pcis->A_IB; 395a3df083aSStefano Zampini ctx->work = work; 396a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 397a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 398a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 399a3df083aSStefano Zampini pcis->A_IB = A_IB; 400a3df083aSStefano Zampini 401a3df083aSStefano Zampini /* A_BI as A_IB^T */ 402a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 403a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 404a3df083aSStefano Zampini pcis->A_BI = A_BI; 405a3df083aSStefano Zampini } else { 4061dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 4071dd7afcfSStefano Zampini PetscFunctionReturn(0); 4081dd7afcfSStefano Zampini } 409a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 410a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 411a3df083aSStefano Zampini pcis->A_IB = ctx->A; 4121dd7afcfSStefano Zampini ctx->A = NULL; 4131dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 4141dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 4151dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 4161dd7afcfSStefano Zampini if (ctx->free) { 417059032f7SStefano Zampini PetscInt i; 4181dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 419059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 420059032f7SStefano Zampini } 421059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 422059032f7SStefano Zampini } 423a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 424a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 425a3df083aSStefano Zampini } 426a3df083aSStefano Zampini PetscFunctionReturn(0); 427a3df083aSStefano Zampini } 428a3df083aSStefano Zampini 429a3df083aSStefano Zampini /* used just in bddc debug mode */ 430a3df083aSStefano Zampini #undef __FUNCT__ 431a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 432a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 433a3df083aSStefano Zampini { 434a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 435a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 436a3df083aSStefano Zampini Mat An; 437a3df083aSStefano Zampini PetscErrorCode ierr; 438a3df083aSStefano Zampini 439a3df083aSStefano Zampini PetscFunctionBegin; 440a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 441a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 442a3df083aSStefano Zampini if (is1) { 443a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 444a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 445a3df083aSStefano Zampini } else { 446a3df083aSStefano Zampini *B = An; 447a3df083aSStefano Zampini } 448a3df083aSStefano Zampini PetscFunctionReturn(0); 449a3df083aSStefano Zampini } 450a3df083aSStefano Zampini 4511cf9b237SStefano Zampini /* TODO: add reuse flag */ 4521cf9b237SStefano Zampini #undef __FUNCT__ 4531cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 4541cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 4551cf9b237SStefano Zampini { 4561cf9b237SStefano Zampini Mat Bt; 4571cf9b237SStefano Zampini PetscScalar *a,*bdata; 4581cf9b237SStefano Zampini const PetscInt *ii,*ij; 4591cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 4601cf9b237SStefano Zampini PetscBool flg_row; 4611cf9b237SStefano Zampini PetscErrorCode ierr; 4621cf9b237SStefano Zampini 4631cf9b237SStefano Zampini PetscFunctionBegin; 4641cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 4651cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 4661cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 4671cf9b237SStefano Zampini nnz = n; 4681cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 4691cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 4701cf9b237SStefano Zampini } 4711cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 4721cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 4731cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 4741cf9b237SStefano Zampini nnz = 0; 4751cf9b237SStefano Zampini bii[0] = 0; 4761cf9b237SStefano Zampini for (i=0;i<n;i++) { 4771cf9b237SStefano Zampini PetscInt j; 4781cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 4791cf9b237SStefano Zampini PetscScalar entry = a[j]; 4801cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 4811cf9b237SStefano Zampini bij[nnz] = ij[j]; 4821cf9b237SStefano Zampini bdata[nnz] = entry; 4831cf9b237SStefano Zampini nnz++; 4841cf9b237SStefano Zampini } 4851cf9b237SStefano Zampini } 4861cf9b237SStefano Zampini bii[i+1] = nnz; 4871cf9b237SStefano Zampini } 4881cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 4891cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 4901cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 4911cf9b237SStefano Zampini { 4921cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 4931cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 4941cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 4951cf9b237SStefano Zampini } 4961cf9b237SStefano Zampini *B = Bt; 4971cf9b237SStefano Zampini PetscFunctionReturn(0); 4981cf9b237SStefano Zampini } 4991cf9b237SStefano Zampini 500674ae819SStefano Zampini #undef __FUNCT__ 5014f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 5024f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 5034f1b2e48SStefano Zampini { 5044f1b2e48SStefano Zampini Mat B; 5054f1b2e48SStefano Zampini IS is_dummy,*cc_n; 5064f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 5074f1b2e48SStefano Zampini PCBDDCGraph graph; 5084f1b2e48SStefano Zampini PetscInt i,n; 5094f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 5104f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 5114f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 5124f1b2e48SStefano Zampini PetscErrorCode ierr; 5134f1b2e48SStefano Zampini 5144f1b2e48SStefano Zampini PetscFunctionBegin; 51563c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 51663c961adSStefano Zampini *ncc = 0; 51763c961adSStefano Zampini *cc = NULL; 51863c961adSStefano Zampini PetscFunctionReturn(0); 51963c961adSStefano Zampini } 5204f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 5214f1b2e48SStefano Zampini if (!isseqaij && filter) { 5221cf9b237SStefano Zampini PetscBool isseqdense; 5231cf9b237SStefano Zampini 5241cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 5251cf9b237SStefano Zampini if (!isseqdense) { 5264f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 5271cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 5281cf9b237SStefano Zampini PetscScalar *array; 5291cf9b237SStefano Zampini PetscReal chop=1.e-6; 5301cf9b237SStefano Zampini 5311cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 5321cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 5331cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 5341cf9b237SStefano Zampini for (i=0;i<n;i++) { 5351cf9b237SStefano Zampini PetscInt j; 5361cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 5371cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 5381cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 5391cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 5401cf9b237SStefano Zampini } 5411cf9b237SStefano Zampini } 5421cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 5439d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 5441cf9b237SStefano Zampini } 5454f1b2e48SStefano Zampini } else { 5464f1b2e48SStefano Zampini B = A; 5474f1b2e48SStefano Zampini } 5484f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5494f1b2e48SStefano Zampini 5504f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 5514f1b2e48SStefano Zampini if (filter) { 5524f1b2e48SStefano Zampini PetscScalar *data; 5534f1b2e48SStefano Zampini PetscInt j,cum; 5544f1b2e48SStefano Zampini 5554f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 5564f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 5574f1b2e48SStefano Zampini cum = 0; 5584f1b2e48SStefano Zampini for (i=0;i<n;i++) { 5594f1b2e48SStefano Zampini PetscInt t; 5604f1b2e48SStefano Zampini 5614f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 5624f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 5634f1b2e48SStefano Zampini continue; 5644f1b2e48SStefano Zampini } 5654f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 5664f1b2e48SStefano Zampini } 5674f1b2e48SStefano Zampini t = xadj_filtered[i]; 5684f1b2e48SStefano Zampini xadj_filtered[i] = cum; 5694f1b2e48SStefano Zampini cum += t; 5704f1b2e48SStefano Zampini } 5714f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 5724f1b2e48SStefano Zampini } else { 5734f1b2e48SStefano Zampini xadj_filtered = NULL; 5744f1b2e48SStefano Zampini adjncy_filtered = NULL; 5754f1b2e48SStefano Zampini } 5764f1b2e48SStefano Zampini 5774f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 5784f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 5794f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 5804f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 5814f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 5824f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 5834f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 5844f1b2e48SStefano Zampini if (xadj_filtered) { 5854f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 5864f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 5874f1b2e48SStefano Zampini } else { 5884f1b2e48SStefano Zampini graph->xadj = xadj; 5894f1b2e48SStefano Zampini graph->adjncy = adjncy; 5904f1b2e48SStefano Zampini } 5914f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 5924f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5934f1b2e48SStefano Zampini /* partial clean up */ 5944f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 5954f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5961cf9b237SStefano Zampini if (A != B) { 5974f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 5984f1b2e48SStefano Zampini } 5994f1b2e48SStefano Zampini 6004f1b2e48SStefano Zampini /* get back data */ 6011cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 6021cf9b237SStefano Zampini if (cc) { 6034f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 6044f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 6054f1b2e48SStefano 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); 6064f1b2e48SStefano Zampini } 6074f1b2e48SStefano Zampini *cc = cc_n; 6081cf9b237SStefano Zampini } 6094f1b2e48SStefano Zampini /* clean up graph */ 6104f1b2e48SStefano Zampini graph->xadj = 0; 6114f1b2e48SStefano Zampini graph->adjncy = 0; 6124f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6134f1b2e48SStefano Zampini PetscFunctionReturn(0); 6144f1b2e48SStefano Zampini } 6154f1b2e48SStefano Zampini 6164f1b2e48SStefano Zampini #undef __FUNCT__ 6175408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 6185408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 6195408967cSStefano Zampini { 6205408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6215408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 622dee84bffSStefano Zampini IS dirIS = NULL; 6234f1b2e48SStefano Zampini PetscInt i; 6245408967cSStefano Zampini PetscErrorCode ierr; 6255408967cSStefano Zampini 6265408967cSStefano Zampini PetscFunctionBegin; 627dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 6285408967cSStefano Zampini if (zerodiag) { 6295408967cSStefano Zampini Mat A; 6305408967cSStefano Zampini Vec vec3_N; 6315408967cSStefano Zampini PetscScalar *vals; 6325408967cSStefano Zampini const PetscInt *idxs; 633d12d3064SStefano Zampini PetscInt nz,*count; 6345408967cSStefano Zampini 6355408967cSStefano Zampini /* p0 */ 6365408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 6375408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 6385408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 6395408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 6404f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 6415408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6425408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6435408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6445408967cSStefano Zampini /* v_I */ 6455408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 6465408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 6475408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6485408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 6495408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 6505408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 6515408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6525408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 6535408967cSStefano Zampini if (dirIS) { 6545408967cSStefano Zampini PetscInt n; 6555408967cSStefano Zampini 6565408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 6575408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 6585408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 6595408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6605408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 6615408967cSStefano Zampini } 6625408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 6635408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 6645408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 6655408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 666669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 6675408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 6685408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 669fbfcb133SStefano Zampini if (PetscAbsScalar(vals[0]) > 1.e-1) { 670b9b0e38cSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! b(v_I,p_0) = %1.6e (should be numerically 0.)",PetscAbsScalar(vals[0])); 6715408967cSStefano Zampini } 6725408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6735408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 674d12d3064SStefano Zampini 675d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 676d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 677d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 678d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 679d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 680d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 681d4d8cf7bSStefano Zampini for (i=0;i<nz;i++) { 682d12d3064SStefano Zampini if (count[idxs[i]]) { 683d12d3064SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 684d12d3064SStefano Zampini } 685d4d8cf7bSStefano Zampini } 686d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 687d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 6885408967cSStefano Zampini } 689dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 6905408967cSStefano Zampini 6915408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 6925408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 6934f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 6945408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 6954f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 6965408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 6974f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6984f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 6994f1b2e48SStefano 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); 7004f1b2e48SStefano Zampini } 7015408967cSStefano Zampini } 7025408967cSStefano Zampini PetscFunctionReturn(0); 7035408967cSStefano Zampini } 7045408967cSStefano Zampini 7055408967cSStefano Zampini #undef __FUNCT__ 706339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 707339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 708339f8db1SStefano Zampini { 709339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7104f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 711b0f5fe93SStefano Zampini PetscInt nz,n; 7121f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 7134f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 714339f8db1SStefano Zampini PetscErrorCode ierr; 715339f8db1SStefano Zampini 716339f8db1SStefano Zampini PetscFunctionBegin; 7179f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 7189f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 719a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 720a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 721a3df083aSStefano Zampini } 722a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 723a3df083aSStefano Zampini pcbddc->benign_n = 0; 7241ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 7254f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 7264f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 7274f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 7281ae86dd6SStefano Zampini since the local Schur complements are already SPD 7294f1b2e48SStefano Zampini */ 7304f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 7314f1b2e48SStefano Zampini have_null = PETSC_TRUE; 73240fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 7334f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 7344f1b2e48SStefano Zampini 7354f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 7364f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 7374f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 7384f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 739ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 74040fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 74140fa8d13SStefano Zampini if (!sorted) { 74240fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 74340fa8d13SStefano Zampini } 74440fa8d13SStefano Zampini } else { 74540fa8d13SStefano Zampini pressures = NULL; 74640fa8d13SStefano Zampini } 74797d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 74897d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 74927b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 75097d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 751339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 752339f8db1SStefano Zampini if (!sorted) { 753339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 754339f8db1SStefano Zampini } 755339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 7564f1b2e48SStefano Zampini if (!nz) { 7574f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 7584f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 75940fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 76040fa8d13SStefano Zampini } 7614f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 7624f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 7634f1b2e48SStefano Zampini zerodiag_subs = NULL; 7644f1b2e48SStefano Zampini pcbddc->benign_n = 0; 7651f4df5f7SStefano Zampini n_interior_dofs = 0; 7661f4df5f7SStefano Zampini interior_dofs = NULL; 7671f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 7681f4df5f7SStefano Zampini PetscInt n,i,j; 7691f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 7701f4df5f7SStefano Zampini PetscInt *iwork; 7711f4df5f7SStefano Zampini 7721f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 7731f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 7741f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 7751f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 7761f4df5f7SStefano Zampini for (i=0;i<n_neigh;i++) 7771f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 7781f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 7791f4df5f7SStefano Zampini for (i=0;i<n;i++) 7801f4df5f7SStefano Zampini if (!iwork[i]) 7811f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 7821f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 7831f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 7841f4df5f7SStefano Zampini } 7854f1b2e48SStefano Zampini if (has_null_pressures) { 7864f1b2e48SStefano Zampini IS *subs; 7871f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 7881f4df5f7SStefano Zampini const PetscInt *idxs; 7891f4df5f7SStefano Zampini PetscScalar *array; 7901f4df5f7SStefano Zampini Vec *work; 7911f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 7924f1b2e48SStefano Zampini 7934f1b2e48SStefano Zampini subs = pcbddc->local_subs; 7944f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 7951f4df5f7SStefano Zampini /* these vectors are needed to check if the constant on pressures is in the kernel of the local operator B (i.e. B(v_I,p0) should be zero) */ 7961f4df5f7SStefano Zampini if (pcbddc->current_level) { 7971f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 7981f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 7991f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 8001f4df5f7SStefano Zampini /* work[0] = 1_p */ 8011f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 8021f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 8031f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 8041f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 8051f4df5f7SStefano Zampini /* work[0] = 1_v */ 8061f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 8071f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 8081f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 8091f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 8101f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 8111f4df5f7SStefano Zampini } 8124f1b2e48SStefano Zampini if (nsubs > 1) { 8134f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 8144f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 8154f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 8164f1b2e48SStefano Zampini IS t_zerodiag_subs; 8174f1b2e48SStefano Zampini PetscInt nl; 8184f1b2e48SStefano Zampini 8194f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 8204f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 8214f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 8224f1b2e48SStefano Zampini if (nl) { 8234f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 8244f1b2e48SStefano Zampini 8251f4df5f7SStefano Zampini if (pcbddc->current_level) { 8261f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 8271f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 8281f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 8291f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 8301f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 8311f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 8321f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 8331f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 8341f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 8351f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 8361f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 8371f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 8381f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 8391f4df5f7SStefano Zampini valid = PETSC_FALSE; 8401f4df5f7SStefano Zampini break; 8411f4df5f7SStefano Zampini } 8421f4df5f7SStefano Zampini } 8431f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 8441f4df5f7SStefano Zampini } 8451f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 8461f4df5f7SStefano Zampini IS t_bc; 8471f4df5f7SStefano Zampini PetscInt nzb; 8481f4df5f7SStefano Zampini 8491f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 8501f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 8511f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 8521f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 8531f4df5f7SStefano Zampini } 8541f4df5f7SStefano Zampini if (valid && pressures) { 8554f1b2e48SStefano Zampini IS t_pressure_subs; 8564f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 8574f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 8584f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 8594f1b2e48SStefano Zampini } 8604f1b2e48SStefano Zampini if (valid) { 8614f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 8624f1b2e48SStefano Zampini pcbddc->benign_n++; 8634f1b2e48SStefano Zampini } else { 8644f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 8654f1b2e48SStefano Zampini } 8664f1b2e48SStefano Zampini } 8674f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 8684f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 8694f1b2e48SStefano Zampini } 8704f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 8714f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 8721f4df5f7SStefano Zampini 8731f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 8741f4df5f7SStefano Zampini PetscInt nzb; 8751f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 8761f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 8771f4df5f7SStefano Zampini } 8781f4df5f7SStefano Zampini if (valid && pressures) { 8794f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 8804f1b2e48SStefano Zampini } 8811f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 8821f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 8831f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 8841f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 8851f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 8861f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 8871f4df5f7SStefano Zampini valid = PETSC_FALSE; 8881f4df5f7SStefano Zampini break; 8891f4df5f7SStefano Zampini } 8901f4df5f7SStefano Zampini } 8911f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 8921f4df5f7SStefano Zampini } 8934f1b2e48SStefano Zampini if (valid) { 8944f1b2e48SStefano Zampini pcbddc->benign_n = 1; 895ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 8964f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 8974f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 8984f1b2e48SStefano Zampini } 8994f1b2e48SStefano Zampini } 9001f4df5f7SStefano Zampini if (pcbddc->current_level) { 9011f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 9024f1b2e48SStefano Zampini } 9031f4df5f7SStefano Zampini } 9041f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 9054f1b2e48SStefano Zampini 9064f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 907b9b0e38cSStefano Zampini PetscInt n; 908b9b0e38cSStefano Zampini 9094f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 9104f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 911b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 912b9b0e38cSStefano Zampini if (n) { 9134f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 9144f1b2e48SStefano Zampini have_null = PETSC_FALSE; 9154f1b2e48SStefano Zampini } 916b9b0e38cSStefano Zampini } 9174f1b2e48SStefano Zampini 9184f1b2e48SStefano Zampini /* final check for null pressures */ 9194f1b2e48SStefano Zampini if (zerodiag && pressures) { 9204f1b2e48SStefano Zampini PetscInt nz,np; 9214f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 9224f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 9234f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 9244f1b2e48SStefano Zampini } 9254f1b2e48SStefano Zampini 9264f1b2e48SStefano Zampini if (recompute_zerodiag) { 9274f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 9284f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 9294f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 9304f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 9314f1b2e48SStefano Zampini } else { 9324f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 9334f1b2e48SStefano Zampini 9344f1b2e48SStefano Zampini nzn = 0; 9354f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 9364f1b2e48SStefano Zampini PetscInt ns; 9374f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 9384f1b2e48SStefano Zampini nzn += ns; 9394f1b2e48SStefano Zampini } 9404f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 9414f1b2e48SStefano Zampini nzn = 0; 9424f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 9434f1b2e48SStefano Zampini PetscInt ns,*idxs; 9444f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 9454f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 9464f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 9474f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 9484f1b2e48SStefano Zampini nzn += ns; 9494f1b2e48SStefano Zampini } 9504f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 9514f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 9524f1b2e48SStefano Zampini } 9534f1b2e48SStefano Zampini have_null = PETSC_FALSE; 9544f1b2e48SStefano Zampini } 9554f1b2e48SStefano Zampini 956669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 957a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 958a198735bSStefano Zampini Mat A,loc_divudotp; 959a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 960a198735bSStefano Zampini IS row,col,isused = NULL; 961a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 962a198735bSStefano Zampini 9631f4df5f7SStefano Zampini if (pressures) { 9641f4df5f7SStefano Zampini isused = pressures; 9651f4df5f7SStefano Zampini } else { 9661f4df5f7SStefano Zampini isused = zerodiag; 9671f4df5f7SStefano Zampini } 968a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 969669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 9701ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 9711ae86dd6SStefano Zampini if (!isused && n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Don't know how to extract div u dot p! Please provide the pressure field"); 972a198735bSStefano Zampini n_isused = 0; 973a198735bSStefano Zampini if (isused) { 974a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 975a198735bSStefano Zampini } 976a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 977a198735bSStefano Zampini st = st-n_isused; 9781ae86dd6SStefano Zampini if (n) { 979a198735bSStefano Zampini const PetscInt *gidxs; 980a198735bSStefano Zampini 981a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 982a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 983a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 984a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 985a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 986a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 9871ae86dd6SStefano Zampini } else { 988a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 989a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 990a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 991a198735bSStefano Zampini } 992a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 993a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 994a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 995a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 996a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 997a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 998a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 999a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 1000a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 1001a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 1002a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1003a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1004a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 1005a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 10061ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10071ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10081ae86dd6SStefano Zampini } 1009b3afcdbeSStefano Zampini 1010b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 10114f1b2e48SStefano Zampini if (has_null_pressures) { 10124f1b2e48SStefano Zampini IS zerodiagc; 10134f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 10144f1b2e48SStefano Zampini PetscInt i,s,*nnz; 10154f1b2e48SStefano Zampini 10164f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 1017339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 1018339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 1019339f8db1SStefano Zampini /* local change of basis for pressures */ 1020339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 102197d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 1022339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 1023339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1024339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 10254f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 10264f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 10274f1b2e48SStefano Zampini PetscInt nzs,j; 10284f1b2e48SStefano Zampini 10294f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 10304f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 10314f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 10324f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 10334f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 10344f1b2e48SStefano Zampini } 1035339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 1036339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1037339f8db1SStefano Zampini /* set identity on velocities */ 1038339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 1039339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 1040339f8db1SStefano Zampini } 10414f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 10424f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 10439f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 10444f1b2e48SStefano 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); 1045339f8db1SStefano Zampini /* set change on pressures */ 10464f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 10474f1b2e48SStefano Zampini PetscScalar *array; 10484f1b2e48SStefano Zampini PetscInt nzs; 10494f1b2e48SStefano Zampini 10504f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 10514f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 10524f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 1053339f8db1SStefano Zampini PetscScalar vals[2]; 1054339f8db1SStefano Zampini PetscInt cols[2]; 1055339f8db1SStefano Zampini 1056339f8db1SStefano Zampini cols[0] = idxs[i]; 10574f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 1058339f8db1SStefano Zampini vals[0] = 1.; 1059b0f5fe93SStefano Zampini vals[1] = 1.; 10604f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 1061339f8db1SStefano Zampini } 10624f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 10634f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 10644f1b2e48SStefano Zampini array[nzs-1] = 1.; 10654f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 10664f1b2e48SStefano Zampini /* store local idxs for p0 */ 10674f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 10684f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 1069339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 10704f1b2e48SStefano Zampini } 1071339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1072339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1073a3df083aSStefano Zampini /* project if needed */ 1074a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 10751dd7afcfSStefano Zampini Mat M; 10761dd7afcfSStefano Zampini 10771dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 1078339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 10791dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 10801dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1081a3df083aSStefano Zampini } 10824f1b2e48SStefano Zampini /* store global idxs for p0 */ 10834f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1084339f8db1SStefano Zampini } 1085ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 10864f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 1087b0f5fe93SStefano Zampini 1088b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 1089b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 109027b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 109127b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1092339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 1093339f8db1SStefano Zampini PetscFunctionReturn(0); 1094339f8db1SStefano Zampini } 1095339f8db1SStefano Zampini 1096339f8db1SStefano Zampini #undef __FUNCT__ 1097015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 1098015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 1099efc2fbd9SStefano Zampini { 1100efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1101de9d7bd0SStefano Zampini PetscScalar *array; 1102efc2fbd9SStefano Zampini PetscErrorCode ierr; 1103efc2fbd9SStefano Zampini 1104efc2fbd9SStefano Zampini PetscFunctionBegin; 1105efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 1106efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 11074f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1108efc2fbd9SStefano Zampini } 1109de9d7bd0SStefano Zampini if (get) { 1110efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 11114f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 11124f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 1113efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 1114de9d7bd0SStefano Zampini } else { 1115de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 1116de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1117de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1118de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 1119efc2fbd9SStefano Zampini } 1120efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1121efc2fbd9SStefano Zampini } 1122efc2fbd9SStefano Zampini 1123efc2fbd9SStefano Zampini #undef __FUNCT__ 1124c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 1125c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 1126c263805aSStefano Zampini { 1127c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1128c263805aSStefano Zampini PetscErrorCode ierr; 1129c263805aSStefano Zampini 1130c263805aSStefano Zampini PetscFunctionBegin; 1131c263805aSStefano Zampini /* TODO: add error checking 1132c263805aSStefano Zampini - avoid nested pop (or push) calls. 1133c263805aSStefano Zampini - cannot push before pop. 11341c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 1135c263805aSStefano Zampini */ 11364f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1137efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1138efc2fbd9SStefano Zampini } 1139c263805aSStefano Zampini if (pop) { 1140a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 11414f1b2e48SStefano Zampini IS is_p0; 11424f1b2e48SStefano Zampini MatReuse reuse; 1143c263805aSStefano Zampini 1144c263805aSStefano Zampini /* extract B_0 */ 11454f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 11464f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 11474f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 11484f1b2e48SStefano Zampini } 11494f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 11504f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 1151c263805aSStefano Zampini /* remove rows and cols from local problem */ 1152c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 115397d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 11544f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 11554f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 1156a3df083aSStefano Zampini } else { 1157a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1158a3df083aSStefano Zampini PetscScalar *vals; 1159a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 1160a3df083aSStefano Zampini 1161a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 1162a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 1163a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 11640b5adadeSStefano Zampini PetscInt *nnz; 1165a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 1166a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 1167a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1168331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 1169331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1170331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 1171331e053bSStefano Zampini nnz[i] = n - nnz[i]; 1172331e053bSStefano Zampini } 1173331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 1174331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1175331e053bSStefano Zampini } 1176a3df083aSStefano Zampini 1177a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1178a3df083aSStefano Zampini PetscScalar *array; 1179a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 1180a3df083aSStefano Zampini 1181a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 1182a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1183a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1184a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 1185a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1186a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 1187a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 1188a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 1189a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 1190a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 1191a3df083aSStefano Zampini cum = 0; 1192a3df083aSStefano Zampini for (j=0;j<n;j++) { 119322db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 1194a3df083aSStefano Zampini vals[cum] = array[j]; 1195a3df083aSStefano Zampini idxs_ins[cum] = j; 1196a3df083aSStefano Zampini cum++; 1197a3df083aSStefano Zampini } 1198a3df083aSStefano Zampini } 1199a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 1200a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 1201a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1202a3df083aSStefano Zampini } 1203a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1204a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1205a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 1206a3df083aSStefano Zampini } 1207c263805aSStefano Zampini } else { /* push */ 1208a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 12094f1b2e48SStefano Zampini PetscInt i; 12104f1b2e48SStefano Zampini 12114f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 12124f1b2e48SStefano Zampini PetscScalar *B0_vals; 12134f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 12144f1b2e48SStefano Zampini 12154f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 12164f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 12177b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 12184f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 12194f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 12204f1b2e48SStefano Zampini } 1221c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1222c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1223a3df083aSStefano Zampini } else { 1224a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 1225a3df083aSStefano Zampini } 1226c263805aSStefano Zampini } 1227c263805aSStefano Zampini PetscFunctionReturn(0); 1228c263805aSStefano Zampini } 1229c263805aSStefano Zampini 1230c263805aSStefano Zampini #undef __FUNCT__ 1231b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 123208122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 1233b1b3d7a2SStefano Zampini { 1234b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 123508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 123608122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 123708122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 123808122e43SStefano Zampini PetscScalar *work,lwork; 123908122e43SStefano Zampini PetscScalar *St,*S,*eigv; 124008122e43SStefano Zampini PetscScalar *Sarray,*Starray; 124108122e43SStefano Zampini PetscReal *eigs,thresh; 12421b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 1243f6f667cfSStefano Zampini PetscBool allocated_S_St; 124408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 124508122e43SStefano Zampini PetscReal *rwork; 124608122e43SStefano Zampini #endif 1247b1b3d7a2SStefano Zampini PetscErrorCode ierr; 1248b1b3d7a2SStefano Zampini 1249b1b3d7a2SStefano Zampini PetscFunctionBegin; 1250b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 1251af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 1252af25d912SStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) 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); 125306a4e24aSStefano Zampini 1254fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1255fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1256fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1257fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 12581575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1259fd14bc51SStefano Zampini } 1260fd14bc51SStefano Zampini 1261e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 1262e496cd5dSStefano 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); 1263e496cd5dSStefano Zampini } 1264e496cd5dSStefano Zampini 126508122e43SStefano Zampini /* max size of subsets */ 126608122e43SStefano Zampini mss = 0; 126708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 126808122e43SStefano Zampini PetscInt subset_size; 1269862806e4SStefano Zampini 127008122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 127108122e43SStefano Zampini mss = PetscMax(mss,subset_size); 127208122e43SStefano Zampini } 127308122e43SStefano Zampini 127408122e43SStefano Zampini /* min/max and threshold */ 127508122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 1276f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 127708122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 1278f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 1279f6f667cfSStefano Zampini if (nmin) { 1280f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 1281f6f667cfSStefano Zampini } 128208122e43SStefano Zampini 128308122e43SStefano Zampini /* allocate lapack workspace */ 128408122e43SStefano Zampini cum = cum2 = 0; 128508122e43SStefano Zampini maxneigs = 0; 128608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 128708122e43SStefano Zampini PetscInt n,subset_size; 1288f6f667cfSStefano Zampini 128908122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 129008122e43SStefano Zampini n = PetscMin(subset_size,nmax); 12919162d606SStefano Zampini cum += subset_size; 12929162d606SStefano Zampini cum2 += subset_size*n; 129308122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 129408122e43SStefano Zampini } 129508122e43SStefano Zampini if (mss) { 12969ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 129708122e43SStefano Zampini PetscBLASInt B_itype = 1; 129808122e43SStefano Zampini PetscBLASInt B_N = mss; 12994c6709b3SStefano Zampini PetscReal zero = 0.0; 13004c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 130108122e43SStefano Zampini 130208122e43SStefano Zampini B_lwork = -1; 130308122e43SStefano Zampini S = NULL; 130408122e43SStefano Zampini St = NULL; 1305a58a30b4SStefano Zampini eigs = NULL; 1306a58a30b4SStefano Zampini eigv = NULL; 1307a58a30b4SStefano Zampini B_iwork = NULL; 1308a58a30b4SStefano Zampini B_ifail = NULL; 1309d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1310d1710679SStefano Zampini rwork = NULL; 1311d1710679SStefano Zampini #endif 13128bec7fa6SStefano Zampini thresh = 1.0; 131308122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 131408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 131508122e43SStefano 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)); 131608122e43SStefano Zampini #else 131708122e43SStefano 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)); 131808122e43SStefano Zampini #endif 131908122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 132008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 132108122e43SStefano Zampini } else { 132208122e43SStefano Zampini /* TODO */ 132308122e43SStefano Zampini } 132408122e43SStefano Zampini } else { 132508122e43SStefano Zampini lwork = 0; 132608122e43SStefano Zampini } 132708122e43SStefano Zampini 132808122e43SStefano Zampini nv = 0; 1329d62866d3SStefano 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) */ 1330d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 133108122e43SStefano Zampini } 13324c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 1333f6f667cfSStefano Zampini if (allocated_S_St) { 1334f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 1335f6f667cfSStefano Zampini } 1336f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 133708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 133808122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 133908122e43SStefano Zampini #endif 13409162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 13419162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 13429162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 134308122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 13449162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 134508122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 134608122e43SStefano Zampini 134708122e43SStefano Zampini maxneigs = 0; 134872b8c272SStefano Zampini cum = cumarray = 0; 13499162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 13509162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 1351d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 135208122e43SStefano Zampini const PetscInt *idxs; 135308122e43SStefano Zampini 1354d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 135508122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 135608122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 135708122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 135808122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 13599162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 13609162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 136108122e43SStefano Zampini } 1362d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 136308122e43SStefano Zampini } 136408122e43SStefano Zampini 136508122e43SStefano Zampini if (mss) { /* multilevel */ 136608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 136708122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 136808122e43SStefano Zampini } 136908122e43SStefano Zampini 1370ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 137108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 137208122e43SStefano Zampini const PetscInt *idxs; 13739d54b7f4SStefano Zampini PetscReal upper,lower; 1374862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 137508122e43SStefano Zampini PetscBLASInt B_N; 1376aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 137708122e43SStefano Zampini 13789d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 13799d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 13809d54b7f4SStefano Zampini lower = thresh; 13819d54b7f4SStefano Zampini } else { 13829d54b7f4SStefano Zampini upper = 1./thresh; 13839d54b7f4SStefano Zampini lower = 0.; 13849d54b7f4SStefano Zampini } 1385862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 1386ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 1387f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 1388f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 13899ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 1390aff50787SStefano Zampini PetscInt j,k; 1391aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 1392aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 1393aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 139408122e43SStefano Zampini } 139508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 1396aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 1397aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 1398aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 1399aff50787SStefano Zampini } 140008122e43SStefano Zampini } 140108122e43SStefano Zampini } else { 140208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 140308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 140408122e43SStefano Zampini } 14058bec7fa6SStefano Zampini } else { 1406f6f667cfSStefano Zampini S = Sarray + cumarray; 1407f6f667cfSStefano Zampini St = Starray + cumarray; 14088bec7fa6SStefano Zampini } 1409aff50787SStefano Zampini /* see if we can save some work */ 1410b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 1411aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1412aff50787SStefano Zampini } 1413aff50787SStefano Zampini 1414b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 1415aff50787SStefano Zampini B_neigs = 0; 1416aff50787SStefano Zampini } else { 14179ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 141808122e43SStefano Zampini PetscBLASInt B_itype = 1; 1419f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 14204c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 14219552c7c7SStefano Zampini PetscInt nmin_s; 1422b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 142308122e43SStefano Zampini 1424fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 14258bec7fa6SStefano 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]]); 1426fd14bc51SStefano Zampini } 1427d16cbb6bSStefano Zampini 1428b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 1429b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 1430b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 1431b7ab4a40SStefano Zampini } 1432b7ab4a40SStefano Zampini 143308122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1434b7ab4a40SStefano Zampini if (compute_range) { 1435d16cbb6bSStefano Zampini 1436d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 143708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 14389d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 143908122e43SStefano Zampini #else 14409d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 144108122e43SStefano Zampini #endif 1442b7ab4a40SStefano Zampini } else if (!same_data) { 1443d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1444d16cbb6bSStefano Zampini B_IL = 1; 1445d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 14469d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 1447d16cbb6bSStefano Zampini #else 14489d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 1449d16cbb6bSStefano Zampini #endif 1450b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 1451b7ab4a40SStefano Zampini PetscInt k; 1452b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 1453b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 1454b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 1455b7ab4a40SStefano Zampini nmin = nmax; 1456b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 1457b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 1458b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 1459b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 1460b7ab4a40SStefano Zampini } 1461d16cbb6bSStefano Zampini } 146208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 146308122e43SStefano Zampini if (B_ierr) { 14646c4ed002SBarry Smith if (B_ierr < 0 ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 14656c4ed002SBarry Smith else if (B_ierr <= B_N) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 14666c4ed002SBarry Smith else 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); 146708122e43SStefano Zampini } 146808122e43SStefano Zampini 146908122e43SStefano Zampini if (B_neigs > nmax) { 1470fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1471fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1472fd14bc51SStefano Zampini } 14739d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 147408122e43SStefano Zampini B_neigs = nmax; 147508122e43SStefano Zampini } 147608122e43SStefano Zampini 14779552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 14789552c7c7SStefano Zampini if (B_neigs < nmin_s) { 147908122e43SStefano Zampini PetscBLASInt B_neigs2; 148008122e43SStefano Zampini 14819d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1482f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 14839d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 14849d54b7f4SStefano Zampini } else { 14859d54b7f4SStefano Zampini B_IL = B_neigs + 1; 14869d54b7f4SStefano Zampini B_IU = nmin_s; 14879d54b7f4SStefano Zampini } 1488fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1489fd14bc51SStefano 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); 1490fd14bc51SStefano Zampini } 14919ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 14921ae86dd6SStefano Zampini PetscInt j,k; 149308122e43SStefano Zampini for (j=0;j<subset_size;j++) { 14941ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 14951ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 14961ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 149708122e43SStefano Zampini } 149808122e43SStefano Zampini } 149908122e43SStefano Zampini } else { 150008122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 150108122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 150208122e43SStefano Zampini } 150308122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 150408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 15059d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&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)); 150608122e43SStefano Zampini #else 15079d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&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)); 150808122e43SStefano Zampini #endif 150908122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 151008122e43SStefano Zampini B_neigs += B_neigs2; 151108122e43SStefano Zampini } 151208122e43SStefano Zampini if (B_ierr) { 15136c4ed002SBarry Smith if (B_ierr < 0 ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 15146c4ed002SBarry Smith else if (B_ierr <= B_N) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 15156c4ed002SBarry Smith else 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); 151608122e43SStefano Zampini } 1517fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1518ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 151908122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 152008122e43SStefano Zampini if (eigs[j] == 0.0) { 1521ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 152208122e43SStefano Zampini } else { 15239d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1524ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 15259d54b7f4SStefano Zampini } else { 15269d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 15279d54b7f4SStefano Zampini } 1528fd14bc51SStefano Zampini } 152908122e43SStefano Zampini } 153008122e43SStefano Zampini } 153108122e43SStefano Zampini } else { 153208122e43SStefano Zampini /* TODO */ 153308122e43SStefano Zampini } 1534aff50787SStefano Zampini } 15356c3e6151SStefano Zampini /* change the basis back to the original one */ 15366c3e6151SStefano Zampini if (sub_schurs->change) { 153772b8c272SStefano Zampini Mat change,phi,phit; 15386c3e6151SStefano Zampini 15396c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 15406c3e6151SStefano Zampini PetscInt ii; 15416c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 15426c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 15436c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 15446c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 15456c3e6151SStefano Zampini } 15466c3e6151SStefano Zampini } 15476c3e6151SStefano Zampini } 154872b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 15496c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 155072b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 15516c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 15526c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 15536c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 15546c3e6151SStefano Zampini } 15558bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 15568bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 15579162d606SStefano Zampini if (B_neigs) { 15589162d606SStefano 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); 1559fd14bc51SStefano Zampini 1560fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 15619552c7c7SStefano Zampini PetscInt ii; 15629552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1563ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 15649552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1565ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1566ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1567ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1568ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1569ac47001eSStefano Zampini #else 1570ac47001eSStefano 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); 1571ac47001eSStefano Zampini #endif 15729552c7c7SStefano Zampini } 15739552c7c7SStefano Zampini } 1574fd14bc51SStefano Zampini } 15759162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 15769162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 15779162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 15789162d606SStefano Zampini cum++; 157908122e43SStefano Zampini } 158008122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 158108122e43SStefano Zampini /* shift for next computation */ 158208122e43SStefano Zampini cumarray += subset_size*subset_size; 158308122e43SStefano Zampini } 1584fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1585fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1586fd14bc51SStefano Zampini } 158708122e43SStefano Zampini 158808122e43SStefano Zampini if (mss) { 158908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 159008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1591f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1592f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1593f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 159408122e43SStefano Zampini } 1595f6f667cfSStefano Zampini if (allocated_S_St) { 1596f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1597f6f667cfSStefano Zampini } 1598f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 159908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 160008122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 160108122e43SStefano Zampini #endif 160208122e43SStefano Zampini if (pcbddc->dbg_flag) { 16031b968477SStefano Zampini PetscInt maxneigs_r; 1604b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 16059b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 160608122e43SStefano Zampini } 160708122e43SStefano Zampini PetscFunctionReturn(0); 160808122e43SStefano Zampini } 1609b1b3d7a2SStefano Zampini 1610674ae819SStefano Zampini #undef __FUNCT__ 1611c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1612c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1613c8587f34SStefano Zampini { 16148629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1615c8587f34SStefano Zampini PetscErrorCode ierr; 1616c8587f34SStefano Zampini 1617c8587f34SStefano Zampini PetscFunctionBegin; 1618f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 16195e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1620c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1621c8587f34SStefano Zampini 1622684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 16230fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1624684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1625c8587f34SStefano Zampini 16268629588bSStefano Zampini /* 16278629588bSStefano Zampini Setup local correction and local part of coarse basis. 16288629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 16298629588bSStefano Zampini */ 163047f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 16318629588bSStefano Zampini 16328629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 16338629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 16348629588bSStefano Zampini 16358629588bSStefano Zampini /* free */ 16368629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1637c8587f34SStefano Zampini PetscFunctionReturn(0); 1638c8587f34SStefano Zampini } 1639c8587f34SStefano Zampini 1640c8587f34SStefano Zampini #undef __FUNCT__ 1641674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1642674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1643674ae819SStefano Zampini { 1644674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1645674ae819SStefano Zampini PetscErrorCode ierr; 1646674ae819SStefano Zampini 1647674ae819SStefano Zampini PetscFunctionBegin; 1648674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1649674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 165030368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1651674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1652785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1653674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1654f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1655f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1656785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 165763602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 165863602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1659674ae819SStefano Zampini PetscFunctionReturn(0); 1660674ae819SStefano Zampini } 1661674ae819SStefano Zampini 1662674ae819SStefano Zampini #undef __FUNCT__ 1663674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1664674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1665674ae819SStefano Zampini { 1666674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16674f1b2e48SStefano Zampini PetscInt i; 1668674ae819SStefano Zampini PetscErrorCode ierr; 1669674ae819SStefano Zampini 1670674ae819SStefano Zampini PetscFunctionBegin; 1671b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1672674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 167316909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 16741dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 1675674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1676669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 1677*fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 1678674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 16794f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 16804f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 16814f1b2e48SStefano Zampini } 16824f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1683b334f244SStefano Zampini if (pcbddc->sub_schurs) { 1684b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1685b334f244SStefano Zampini } 1686674ae819SStefano Zampini PetscFunctionReturn(0); 1687674ae819SStefano Zampini } 1688674ae819SStefano Zampini 1689674ae819SStefano Zampini #undef __FUNCT__ 1690674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1691674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1692674ae819SStefano Zampini { 1693674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1694674ae819SStefano Zampini PetscErrorCode ierr; 1695674ae819SStefano Zampini 1696674ae819SStefano Zampini PetscFunctionBegin; 1697674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 169858da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1699ca92afb2SStefano Zampini PetscScalar *array; 170006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 170106656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 170258da7f69SStefano Zampini } 1703674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1704674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 170515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 170615aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1707674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1708674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1709674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 171006656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1711674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1712674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 17138ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1714674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1715674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1716674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1717f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1718f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1719f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1720f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1721727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 17220e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1723f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 172470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 172581d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 17260369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 17271dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 17284f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 17298b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1730ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1731ca92afb2SStefano Zampini PetscInt i; 1732ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1733ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1734ca92afb2SStefano Zampini } 1735ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1736ca92afb2SStefano Zampini } 17374f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1738674ae819SStefano Zampini PetscFunctionReturn(0); 1739674ae819SStefano Zampini } 1740674ae819SStefano Zampini 1741674ae819SStefano Zampini #undef __FUNCT__ 1742f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1743f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 17446bfb1811SStefano Zampini { 17456bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 17466bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 17476bfb1811SStefano Zampini VecType impVecType; 17484f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 17496bfb1811SStefano Zampini PetscErrorCode ierr; 17506bfb1811SStefano Zampini 17516bfb1811SStefano Zampini PetscFunctionBegin; 17526c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1753e7b262bdSStefano Zampini /* get sizes */ 17544f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1755b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 17566bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1757e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1758e7b262bdSStefano Zampini /* R nodes */ 1759e7b262bdSStefano Zampini old_size = -1; 1760e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1761e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1762e7b262bdSStefano Zampini } 1763e7b262bdSStefano Zampini if (n_R != old_size) { 1764e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1765e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 17666bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 17676bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 17686bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 17696bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1770e7b262bdSStefano Zampini } 1771e7b262bdSStefano Zampini /* local primal dofs */ 1772e7b262bdSStefano Zampini old_size = -1; 1773e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1774e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1775e7b262bdSStefano Zampini } 1776e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1777e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 177883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1779e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 17806bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1781e7b262bdSStefano Zampini } 1782e7b262bdSStefano Zampini /* local explicit constraints */ 1783e7b262bdSStefano Zampini old_size = -1; 1784e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1785e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1786e7b262bdSStefano Zampini } 1787e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1788e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 178983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 179083b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 179183b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 179283b7ccabSStefano Zampini } 17936bfb1811SStefano Zampini PetscFunctionReturn(0); 17946bfb1811SStefano Zampini } 17956bfb1811SStefano Zampini 17966bfb1811SStefano Zampini #undef __FUNCT__ 179747f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 179847f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 179988ebb749SStefano Zampini { 180025084f0cSStefano Zampini PetscErrorCode ierr; 180125084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 180288ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 180388ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1804d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 180525084f0cSStefano Zampini /* submatrices of local problem */ 180680677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 180706656605SStefano Zampini /* submatrices of local coarse problem */ 180806656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 180925084f0cSStefano Zampini /* working matrices */ 181006656605SStefano Zampini Mat C_CR; 181125084f0cSStefano Zampini /* additional working stuff */ 181206656605SStefano Zampini PC pc_R; 18134f1b2e48SStefano Zampini Mat F; 18145cbda25cSStefano Zampini Vec dummy_vec; 1815a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 181625084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 181706656605SStefano Zampini PetscScalar *work; 181806656605SStefano Zampini PetscInt *idx_V_B; 1819ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 182006656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1821ffd830a3SStefano Zampini 182225084f0cSStefano Zampini /* some shortcuts to scalars */ 182306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 182488ebb749SStefano Zampini 182588ebb749SStefano Zampini PetscFunctionBegin; 1826ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1827ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1828ffd830a3SStefano Zampini } 1829ffd830a3SStefano Zampini 1830ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1831b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 18324f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1833b371cd4fSStefano Zampini n_B = pcis->n_B; 1834b371cd4fSStefano Zampini n_D = pcis->n - n_B; 183588ebb749SStefano Zampini n_R = pcis->n - n_vertices; 183688ebb749SStefano Zampini 183788ebb749SStefano Zampini /* vertices in boundary numbering */ 1838785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 18390e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 18406c4ed002SBarry Smith if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D\n",n_vertices,i); 184188ebb749SStefano Zampini 184206656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1843019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 184406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 184506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 184606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 184706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 184806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 184906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 185006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 185106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 185206656605SStefano Zampini 185306656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 185406656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 185506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 185606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 185706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1858ffd830a3SStefano Zampini lda_rhs = n_R; 1859a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 186006656605SStefano Zampini if (isLU || isILU || isCHOL) { 186106656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1862b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 1863df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1864d62866d3SStefano Zampini MatFactorType type; 1865d62866d3SStefano Zampini 1866df4d28bfSStefano Zampini F = reuse_solver->F; 18676816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1868d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1869ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 187022db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 187106656605SStefano Zampini } else { 187206656605SStefano Zampini F = NULL; 187306656605SStefano Zampini } 187406656605SStefano Zampini 1875ffd830a3SStefano Zampini /* allocate workspace */ 1876ffd830a3SStefano Zampini n = 0; 1877ffd830a3SStefano Zampini if (n_constraints) { 1878ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1879ffd830a3SStefano Zampini } 1880ffd830a3SStefano Zampini if (n_vertices) { 1881ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1882ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1883ffd830a3SStefano Zampini } 1884ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1885ffd830a3SStefano Zampini 18865cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 18875cbda25cSStefano Zampini dummy_vec = NULL; 18885cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 18895cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 18905cbda25cSStefano Zampini } 18915cbda25cSStefano Zampini 189288ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 189388ebb749SStefano Zampini if (n_constraints) { 189472b8c272SStefano Zampini Mat M1,M2,M3,C_B; 189506656605SStefano Zampini IS is_aux; 189680677318SStefano Zampini PetscScalar *array,*array2; 189706656605SStefano Zampini 1898f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 189980677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 190088ebb749SStefano Zampini 190125084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 190225084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 19038ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 190472b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 190588ebb749SStefano Zampini 190680677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 190780677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1908ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 190988ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 191006656605SStefano Zampini const PetscScalar *row_cmat_values; 191106656605SStefano Zampini const PetscInt *row_cmat_indices; 191206656605SStefano Zampini PetscInt size_of_constraint,j; 191388ebb749SStefano Zampini 191406656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 191506656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1916ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 191706656605SStefano Zampini } 191806656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 191906656605SStefano Zampini } 1920ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 192106656605SStefano Zampini if (F) { 192206656605SStefano Zampini Mat B; 192306656605SStefano Zampini 1924ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1925a3df083aSStefano Zampini if (need_benign_correction) { 1926df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1927a3df083aSStefano Zampini 192872b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 192972b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 1930a3df083aSStefano Zampini } 193180677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1932a3df083aSStefano Zampini if (need_benign_correction) { 1933a3df083aSStefano Zampini PetscScalar *marr; 1934df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1935a3df083aSStefano Zampini 1936a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 19375cbda25cSStefano Zampini if (lda_rhs != n_R) { 19385cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 19395cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 19405cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 19415cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 19425cbda25cSStefano Zampini } 19435cbda25cSStefano Zampini } else { 1944a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1945a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 19465cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 1947a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1948a3df083aSStefano Zampini } 19495cbda25cSStefano Zampini } 1950a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1951a3df083aSStefano Zampini } 195206656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 195306656605SStefano Zampini } else { 195480677318SStefano Zampini PetscScalar *marr; 195580677318SStefano Zampini 195680677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 195706656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1958ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1959ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 196006656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 196106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 196206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 196306656605SStefano Zampini } 196480677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 196506656605SStefano Zampini } 196680677318SStefano Zampini if (!pcbddc->switch_static) { 196780677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 196880677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 196980677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 197080677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1971ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 197280677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 197380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 197480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 197580677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 197680677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 197780677318SStefano Zampini } 197880677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 197980677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 198072b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 198180677318SStefano Zampini } else { 1982ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1983ffd830a3SStefano Zampini IS dummy; 1984ffd830a3SStefano Zampini 1985ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 198672b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1987ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1988ffd830a3SStefano Zampini } else { 198980677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 199080677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1991ffd830a3SStefano Zampini } 199225084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 199380677318SStefano Zampini } 199480677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 199580677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 199680677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 199706656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 199806656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 199980677318SStefano Zampini if (isCHOL) { 200080677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 200180677318SStefano Zampini } else { 200225084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 200380677318SStefano Zampini } 200480677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 200506656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 200625084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 200725084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 200825084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 200980677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 201072b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 201172b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 201206656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 201306656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 2014f4ddd8eeSStefano Zampini } 2015fc227af8SStefano Zampini 2016fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 201788ebb749SStefano Zampini if (n_vertices) { 201806656605SStefano Zampini IS is_aux; 20193a50541eSStefano Zampini 2020b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 20216816873aSStefano Zampini IS tis; 20226816873aSStefano Zampini 20236816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 20246816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 20256816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 20266816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 20276816873aSStefano Zampini } else { 20283a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 20296816873aSStefano Zampini } 20309577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 20319577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 203204708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 203325084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 203488ebb749SStefano Zampini } 203588ebb749SStefano Zampini 203688ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 2037f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 203806656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 203906656605SStefano Zampini if (pcbddc->coarse_phi_D) { 204006656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 204106656605SStefano Zampini } 2042f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 204306656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 204406656605SStefano Zampini PetscScalar *marray; 204506656605SStefano Zampini 204606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 204706656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 2048f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2049f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 2050f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 2051f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2052f4ddd8eeSStefano Zampini } 2053f4ddd8eeSStefano Zampini } 205406656605SStefano Zampini 2055f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 205606656605SStefano Zampini PetscScalar *marray; 205788ebb749SStefano Zampini 205806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 20598eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 206006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 206188ebb749SStefano Zampini } 20623301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 206306656605SStefano Zampini n *= 2; 206488ebb749SStefano Zampini } 206506656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 206606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 206706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 20688eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 206906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 207006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 207188ebb749SStefano Zampini } 20723301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 207306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 20748eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 207506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 207606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 207788ebb749SStefano Zampini } 207888ebb749SStefano Zampini } else { 2079c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 2080c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 20811b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2082c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 2083c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 2084c0553b1fSStefano Zampini } 208588ebb749SStefano Zampini } 208606656605SStefano Zampini } 2087019a44ceSStefano Zampini 208806656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 20894f1b2e48SStefano Zampini p0_lidx_I = NULL; 20904f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 2091d12edf2fSStefano Zampini const PetscInt *idxs; 2092d12edf2fSStefano Zampini 2093d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 20944f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 20954f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20964f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 20974f1b2e48SStefano Zampini } 2098d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 2099d12edf2fSStefano Zampini } 2100d16cbb6bSStefano Zampini 210106656605SStefano Zampini /* vertices */ 210206656605SStefano Zampini if (n_vertices) { 210316f15bc4SStefano Zampini 2104af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 210504708bb6SStefano Zampini 210616f15bc4SStefano Zampini if (n_R) { 210714393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 210806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 210916f15bc4SStefano Zampini PetscScalar *x,*y; 211004708bb6SStefano Zampini PetscBool isseqaij; 211106656605SStefano Zampini 211221eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 211314393ed6SStefano Zampini if (need_benign_correction) { 211414393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 211514393ed6SStefano Zampini IS is_p0; 211614393ed6SStefano Zampini PetscInt *idxs_p0,n; 211714393ed6SStefano Zampini 211814393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 211914393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 212014393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 2121af25d912SStefano Zampini if (n != pcbddc->benign_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %d != %d\n",n,pcbddc->benign_n); 212214393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 212314393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 212414393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 212514393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 212614393ed6SStefano Zampini } 212714393ed6SStefano Zampini 2128ffd830a3SStefano Zampini if (lda_rhs == n_R) { 2129af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2130ffd830a3SStefano Zampini } else { 2131ca92afb2SStefano Zampini PetscScalar *av,*array; 2132ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 2133ca92afb2SStefano Zampini PetscInt n; 2134ca92afb2SStefano Zampini PetscBool flg_row; 2135ffd830a3SStefano Zampini 2136ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 2137ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 21389d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2139ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2140ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 2141ca92afb2SStefano Zampini for (i=0;i<n;i++) { 2142ca92afb2SStefano Zampini PetscInt j; 2143ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 2144ffd830a3SStefano Zampini } 2145ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2146ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2147ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 2148ffd830a3SStefano Zampini } 2149ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2150a3df083aSStefano Zampini if (need_benign_correction) { 2151df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2152a3df083aSStefano Zampini PetscScalar *marr; 2153a3df083aSStefano Zampini 2154a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 215514393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 215614393ed6SStefano Zampini 215714393ed6SStefano Zampini | 0 0 0 | (V) 215814393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 215914393ed6SStefano Zampini | 0 0 -1 | (p0) 216014393ed6SStefano Zampini 216114393ed6SStefano Zampini */ 2162df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 216314393ed6SStefano Zampini const PetscScalar *vals; 216414393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 216514393ed6SStefano Zampini PetscInt n,j,nz; 216614393ed6SStefano Zampini 2167df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2168df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 216914393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 217014393ed6SStefano Zampini for (j=0;j<n;j++) { 217114393ed6SStefano Zampini PetscScalar val = vals[j]; 217214393ed6SStefano Zampini PetscInt k,col = idxs[j]; 217314393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 217414393ed6SStefano Zampini } 217514393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2176df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 217714393ed6SStefano Zampini } 217872b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 217972b8c272SStefano Zampini } 218072b8c272SStefano Zampini if (F) { 218114393ed6SStefano Zampini /* need to correct the rhs */ 218272b8c272SStefano Zampini if (need_benign_correction) { 218372b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 218472b8c272SStefano Zampini PetscScalar *marr; 218572b8c272SStefano Zampini 218672b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 21875cbda25cSStefano Zampini if (lda_rhs != n_R) { 21885cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 21895cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 21905cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 21915cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 21925cbda25cSStefano Zampini } 21935cbda25cSStefano Zampini } else { 2194a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2195a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 21965cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2197a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2198a3df083aSStefano Zampini } 21995cbda25cSStefano Zampini } 2200a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 2201a3df083aSStefano Zampini } 220206656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 220314393ed6SStefano Zampini /* need to correct the solution */ 2204a3df083aSStefano Zampini if (need_benign_correction) { 2205df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2206a3df083aSStefano Zampini PetscScalar *marr; 2207a3df083aSStefano Zampini 2208a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 22095cbda25cSStefano Zampini if (lda_rhs != n_R) { 22105cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 22115cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 22125cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 22135cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 22145cbda25cSStefano Zampini } 22155cbda25cSStefano Zampini } else { 2216a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2217a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 22185cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2219a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2220a3df083aSStefano Zampini } 22215cbda25cSStefano Zampini } 2222a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 2223a3df083aSStefano Zampini } 222406656605SStefano Zampini } else { 222506656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 222606656605SStefano Zampini for (i=0;i<n_vertices;i++) { 2227ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 2228ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 222906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 223006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 223106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 223206656605SStefano Zampini } 223306656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 223406656605SStefano Zampini } 223580677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2236ffd830a3SStefano Zampini /* S_VV and S_CV */ 223706656605SStefano Zampini if (n_constraints) { 223806656605SStefano Zampini Mat B; 223980677318SStefano Zampini 2240ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 224180677318SStefano Zampini for (i=0;i<n_vertices;i++) { 2242ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 2243ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 224480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 224580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 224680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 224780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 224880677318SStefano Zampini } 2249ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 225080677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 225180677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 2252ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 225380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 225406656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 2255ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 2256ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 225706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 225806656605SStefano Zampini } 225904708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 226004708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 2261511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 226204708bb6SStefano Zampini } 2263ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2264ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 2265ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2266ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 2267ffd830a3SStefano Zampini } 226806656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 226914393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 227014393ed6SStefano Zampini if (need_benign_correction) { 2271df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 227214393ed6SStefano Zampini PetscScalar *marr,*sums; 227314393ed6SStefano Zampini 227414393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 227514393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 2276df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 227714393ed6SStefano Zampini const PetscScalar *vals; 227814393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 227914393ed6SStefano Zampini PetscInt n,j,nz; 228014393ed6SStefano Zampini 2281df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2282df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 228314393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 228414393ed6SStefano Zampini PetscInt k; 228514393ed6SStefano Zampini sums[j] = 0.; 228614393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 228714393ed6SStefano Zampini } 228814393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 228914393ed6SStefano Zampini for (j=0;j<n;j++) { 229014393ed6SStefano Zampini PetscScalar val = vals[j]; 229114393ed6SStefano Zampini PetscInt k; 229214393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 229314393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 229414393ed6SStefano Zampini } 229514393ed6SStefano Zampini } 229614393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2297df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 229814393ed6SStefano Zampini } 229914393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 230014393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 230114393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 230214393ed6SStefano Zampini } 230380677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 230406656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 230506656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 230606656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 230706656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 230806656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 230906656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 231006656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2311d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 2312019a44ceSStefano Zampini } else { 2313d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2314d16cbb6bSStefano Zampini } 231521eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 2316d16cbb6bSStefano Zampini 231706656605SStefano Zampini /* coarse basis functions */ 231806656605SStefano Zampini for (i=0;i<n_vertices;i++) { 231916f15bc4SStefano Zampini PetscScalar *y; 232016f15bc4SStefano Zampini 2321ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 232206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 232306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 232406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232606656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 232706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 232806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 232906656605SStefano Zampini 233006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 23314f1b2e48SStefano Zampini PetscInt j; 23324f1b2e48SStefano Zampini 233306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 233406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 233506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 233606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 233706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 23384f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 233906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 234006656605SStefano Zampini } 234106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 234206656605SStefano Zampini } 234304708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 234404708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 234506656605SStefano Zampini } 23465cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 234706656605SStefano Zampini 234806656605SStefano Zampini if (n_constraints) { 234906656605SStefano Zampini Mat B; 235006656605SStefano Zampini 2351ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 235206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 235380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 235406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 235506656605SStefano Zampini if (n_vertices) { 235680677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 235780677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 235880677318SStefano Zampini } else { 235980677318SStefano Zampini Mat S_VCt; 236080677318SStefano Zampini 2361ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2362ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 236372b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 2364ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 2365ffd830a3SStefano Zampini } 236680677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 236780677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 236880677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 236980677318SStefano Zampini } 237006656605SStefano Zampini } 237106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 237206656605SStefano Zampini /* coarse basis functions */ 237306656605SStefano Zampini for (i=0;i<n_constraints;i++) { 237406656605SStefano Zampini PetscScalar *y; 237506656605SStefano Zampini 2376ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 237706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 237806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 237906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 238006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 238106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 238206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 238306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 23844f1b2e48SStefano Zampini PetscInt j; 23854f1b2e48SStefano Zampini 238606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 238706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 238806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 238906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 239006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 23914f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 239206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 239306656605SStefano Zampini } 239406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 239506656605SStefano Zampini } 239606656605SStefano Zampini } 239780677318SStefano Zampini if (n_constraints) { 239880677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 239980677318SStefano Zampini } 24004f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 240172b8c272SStefano Zampini 240272b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 240372b8c272SStefano Zampini if (pcbddc->benign_n) { 240472b8c272SStefano Zampini Mat B0_B,B0_BPHI; 240572b8c272SStefano Zampini IS is_dummy; 240672b8c272SStefano Zampini PetscScalar *data; 240772b8c272SStefano Zampini PetscInt j; 240872b8c272SStefano Zampini 240972b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 241072b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 241172b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 241272b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 241386c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 241472b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 241572b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 241672b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 241772b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 241872b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 241972b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 242072b8c272SStefano Zampini } 242172b8c272SStefano Zampini } 242272b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 242372b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 242472b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 242572b8c272SStefano Zampini } 2426019a44ceSStefano Zampini 242706656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 24283301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 2429ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 2430ffd830a3SStefano Zampini PetscScalar *marray; 243106656605SStefano Zampini 243206656605SStefano Zampini if (n_constraints) { 2433ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 243406656605SStefano Zampini 2435af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 243606656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 2437ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 243816f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 243906656605SStefano Zampini if (n_vertices) { 2440ffd830a3SStefano Zampini Mat S_VCT; 244106656605SStefano Zampini 244206656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 2443ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 244416f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 244506656605SStefano Zampini } 2446ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 24475b782168SStefano Zampini } else { 24485b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 244906656605SStefano Zampini } 245016f15bc4SStefano Zampini if (n_vertices && n_R) { 2451ffd830a3SStefano Zampini PetscScalar *av,*marray; 2452ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 2453ffd830a3SStefano Zampini PetscInt n; 2454ffd830a3SStefano Zampini PetscBool flg_row; 245506656605SStefano Zampini 2456ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 2457af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 2458ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2459ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 2460ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2461ffd830a3SStefano Zampini for (i=0;i<n;i++) { 2462ffd830a3SStefano Zampini PetscInt j; 2463ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 2464ffd830a3SStefano Zampini } 2465ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2466ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2467ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 246806656605SStefano Zampini } 246906656605SStefano Zampini 2470ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 2471ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2472ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 2473ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 2474ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 247506656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 247606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 247706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 247806656605SStefano Zampini } 2479ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 24805b782168SStefano Zampini if (B_C) { 2481ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 2482ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 2483ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 2484ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 2485ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2486ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2487ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 248806656605SStefano Zampini } 2489ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 24905b782168SStefano Zampini } 24915b782168SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 24925b782168SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 24935b782168SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 24945b782168SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 24955b782168SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 24965b782168SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 24975b782168SStefano Zampini } 24985b782168SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 249906656605SStefano Zampini /* coarse basis functions */ 250006656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 250106656605SStefano Zampini PetscScalar *y; 250206656605SStefano Zampini 2503ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 250406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 250506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 250606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 250706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 250806656605SStefano Zampini if (i<n_vertices) { 250906656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 251006656605SStefano Zampini } 251106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 251206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 251306656605SStefano Zampini 251406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 251506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 251606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 251706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 251806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 251906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 252006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 252106656605SStefano Zampini } 252206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 252306656605SStefano Zampini } 2524ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2525ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 252606656605SStefano Zampini } 2527d62866d3SStefano Zampini /* free memory */ 252888ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 252906656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 253006656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 253106656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 253206656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2533d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2534d62866d3SStefano Zampini if (n_vertices) { 2535d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2536d62866d3SStefano Zampini } 2537d62866d3SStefano Zampini if (n_constraints) { 2538d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2539d62866d3SStefano Zampini } 254088ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 254188ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 254288ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2543d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 254488ebb749SStefano Zampini Mat coarse_sub_mat; 254525084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 254688ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 254788ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 254888ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 25498bec7fa6SStefano Zampini Mat C_B,CPHI; 25508bec7fa6SStefano Zampini IS is_dummy; 25518bec7fa6SStefano Zampini Vec mones; 255288ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 255388ebb749SStefano Zampini PetscReal real_value; 255488ebb749SStefano Zampini 2555a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2556a3df083aSStefano Zampini Mat A; 2557a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2558a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2559a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2560a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2561a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2562a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2563a3df083aSStefano Zampini } else { 256488ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 256588ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 256688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 256788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2568a3df083aSStefano Zampini } 256988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 257088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2571ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 257288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 257388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 257488ebb749SStefano Zampini } 257588ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 257688ebb749SStefano Zampini 257725084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 25783301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 257925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2580ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 258188ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 258288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 258388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 258488ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 258588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 258688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 258788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 258888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 258988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 259088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 259188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 259288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 259388ebb749SStefano Zampini } else { 259488ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 259588ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 259688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 259788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 259888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 259988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 260088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 260188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 260288ebb749SStefano Zampini } 260388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 260488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 260588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2606511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 26074f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2608fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 2609d12edf2fSStefano Zampini PetscScalar *data,*data2; 26104f1b2e48SStefano Zampini PetscInt j; 2611d12edf2fSStefano Zampini 26124f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2613fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 2614d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 261586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2616d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2617d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 26184f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 26194f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2620d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 26214f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 26224f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 26234f1b2e48SStefano Zampini } 2624d12edf2fSStefano Zampini } 2625d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2626d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2627d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2628d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2629d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2630d12edf2fSStefano Zampini } 2631d12edf2fSStefano Zampini #if 0 2632d12edf2fSStefano Zampini { 2633d12edf2fSStefano Zampini PetscViewer viewer; 2634d12edf2fSStefano Zampini char filename[256]; 2635ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2636d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2637d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2638ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2639ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2640ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2641d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 264272b8c272SStefano Zampini if (save_change) { 264372b8c272SStefano Zampini Mat phi_B; 264472b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 264572b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 264672b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 264772b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 264872b8c272SStefano Zampini } else { 2649ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2650ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 265172b8c272SStefano Zampini } 2652ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2653ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2654ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2655ffd830a3SStefano Zampini } 2656ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2657ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2658ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2659ffd830a3SStefano Zampini } 266072b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 2661ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2662ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2663ffd830a3SStefano Zampini } 2664d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2665d12edf2fSStefano Zampini } 2666d12edf2fSStefano Zampini #endif 266781d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 26688bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 26691575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 267006656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 26718bec7fa6SStefano Zampini 26728bec7fa6SStefano Zampini /* check constraints */ 2673a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2674a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 26754f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 26768bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2677a00504b5SStefano Zampini } else { 2678a00504b5SStefano Zampini PetscScalar *data; 2679a00504b5SStefano Zampini Mat tmat; 2680a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2681a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 2682a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2683a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2684a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2685a00504b5SStefano Zampini } 26868bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 26878bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 26888bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 26898bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2690bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2691ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2692bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2693bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2694bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2695bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2696bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 269788ebb749SStefano Zampini } 26988bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 26998bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 27008bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 27018bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 270225084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 270388ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 270488ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 270588ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 270688ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 270788ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 270888ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 270988ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 271088ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 271188ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 271288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2713ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 271488ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 271588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 271688ebb749SStefano Zampini } 271788ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 271888ebb749SStefano Zampini } 27198629588bSStefano Zampini /* get back data */ 27208629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 272188ebb749SStefano Zampini PetscFunctionReturn(0); 272288ebb749SStefano Zampini } 272388ebb749SStefano Zampini 272488ebb749SStefano Zampini #undef __FUNCT__ 2725d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2726d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2727aa0d41d4SStefano Zampini { 2728d65f70fdSStefano Zampini Mat *work_mat; 2729d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2730d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2731c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 2732aa0d41d4SStefano Zampini PetscErrorCode ierr; 2733aa0d41d4SStefano Zampini 2734aa0d41d4SStefano Zampini PetscFunctionBegin; 2735d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2736d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2737d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2738d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2739aa0d41d4SStefano Zampini 2740d65f70fdSStefano Zampini if (!rsorted) { 2741906d46d4SStefano Zampini const PetscInt *idxs; 2742906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2743aa0d41d4SStefano Zampini 2744d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2745d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2746d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2747d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2748aa0d41d4SStefano Zampini } 2749d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2750d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2751d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2752d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2753aa0d41d4SStefano Zampini } 2754d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2755d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2756d65f70fdSStefano Zampini } else { 2757d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2758d65f70fdSStefano Zampini isrow_s = isrow; 2759aa0d41d4SStefano Zampini } 2760906d46d4SStefano Zampini 2761d65f70fdSStefano Zampini if (!csorted) { 2762d65f70fdSStefano Zampini if (isrow == iscol) { 2763d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2764d65f70fdSStefano Zampini iscol_s = isrow_s; 2765d65f70fdSStefano Zampini } else { 2766d65f70fdSStefano Zampini const PetscInt *idxs; 2767d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2768906d46d4SStefano Zampini 2769d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2770d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2771d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2772d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2773d65f70fdSStefano Zampini } 2774d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2775d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2776d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2777d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2778d65f70fdSStefano Zampini } 2779d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2780d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2781d65f70fdSStefano Zampini } 2782d65f70fdSStefano Zampini } else { 2783d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2784d65f70fdSStefano Zampini iscol_s = iscol; 2785d65f70fdSStefano Zampini } 2786d65f70fdSStefano Zampini 2787d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2788d65f70fdSStefano Zampini 2789d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2790906d46d4SStefano Zampini Mat new_mat; 2791d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2792906d46d4SStefano Zampini 2793d65f70fdSStefano Zampini if (!rsorted) { 2794d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2795d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2796d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2797d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2798906d46d4SStefano Zampini } 2799d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2800d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2801d65f70fdSStefano Zampini } else { 2802d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2803906d46d4SStefano Zampini } 2804d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2805d65f70fdSStefano Zampini 2806d65f70fdSStefano Zampini if (!csorted) { 2807d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2808d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2809d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2810d65f70fdSStefano Zampini } else { 2811d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2812d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2813d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2814d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2815d65f70fdSStefano Zampini } 2816d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2817d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2818d65f70fdSStefano Zampini } 2819d65f70fdSStefano Zampini } else { 2820d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2821d65f70fdSStefano Zampini } 2822d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2823d65f70fdSStefano Zampini 2824d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2825d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2826d65f70fdSStefano Zampini work_mat[0] = new_mat; 2827d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2828d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2829d65f70fdSStefano Zampini } 2830d65f70fdSStefano Zampini 2831d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2832d65f70fdSStefano Zampini *B = work_mat[0]; 2833d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2834d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2835d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2836d65f70fdSStefano Zampini PetscFunctionReturn(0); 2837d65f70fdSStefano Zampini } 2838d65f70fdSStefano Zampini 2839d65f70fdSStefano Zampini #undef __FUNCT__ 28405e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 28415e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2842aa0d41d4SStefano Zampini { 2843aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 28445e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2845d65f70fdSStefano Zampini Mat new_mat; 28465e8657edSStefano Zampini IS is_local,is_global; 2847d65f70fdSStefano Zampini PetscInt local_size; 2848d65f70fdSStefano Zampini PetscBool isseqaij; 2849aa0d41d4SStefano Zampini PetscErrorCode ierr; 2850aa0d41d4SStefano Zampini 2851aa0d41d4SStefano Zampini PetscFunctionBegin; 2852aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 28535e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 28545e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2855b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2856aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2857d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2858aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2859906d46d4SStefano Zampini 2860906d46d4SStefano Zampini /* check */ 2861906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2862906d46d4SStefano Zampini Vec x,x_change; 2863906d46d4SStefano Zampini PetscReal error; 2864906d46d4SStefano Zampini 28655e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2866906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 28675e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2868e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2869e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2870d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2871e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2872e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2873906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2874906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2875906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2876906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2877906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2878906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2879906d46d4SStefano Zampini } 2880906d46d4SStefano Zampini 288122d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 28829b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 288322d5777bSStefano Zampini if (isseqaij) { 2884a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2885a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 2886aa0d41d4SStefano Zampini } else { 2887a00504b5SStefano Zampini Mat work_mat; 28881cf9b237SStefano Zampini 2889a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2890aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2891a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 28921d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2893aa0d41d4SStefano Zampini } 28943301b35fSStefano Zampini if (matis->A->symmetric_set) { 28953301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2896e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 28973301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2898e496cd5dSStefano Zampini #endif 28993301b35fSStefano Zampini } 2900d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2901aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2902aa0d41d4SStefano Zampini } 2903aa0d41d4SStefano Zampini 2904aa0d41d4SStefano Zampini #undef __FUNCT__ 2905a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 29068ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2907a64d13efSStefano Zampini { 2908a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2909a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2910d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 291153892102SStefano Zampini PetscInt *idx_R_local=NULL; 29123a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 29133a50541eSStefano Zampini PetscInt vbs,bs; 29146816873aSStefano Zampini PetscBT bitmask=NULL; 2915a64d13efSStefano Zampini PetscErrorCode ierr; 2916a64d13efSStefano Zampini 2917a64d13efSStefano Zampini PetscFunctionBegin; 2918b23d619eSStefano Zampini /* 2919b23d619eSStefano Zampini No need to setup local scatters if 2920b23d619eSStefano Zampini - primal space is unchanged 2921b23d619eSStefano Zampini AND 2922b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2923b23d619eSStefano Zampini AND 2924b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2925b23d619eSStefano Zampini */ 2926b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2927f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2928f4ddd8eeSStefano Zampini } 2929f4ddd8eeSStefano Zampini /* destroy old objects */ 2930f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2931f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2932f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2933a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2934b371cd4fSStefano Zampini n_B = pcis->n_B; 2935b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2936b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 29373a50541eSStefano Zampini 2938a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 29396816873aSStefano Zampini 294053892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 2941b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 2942854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2943a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2944a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 29450e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2946a64d13efSStefano Zampini } 2947a64d13efSStefano Zampini 2948a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 29494641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 29506816873aSStefano Zampini idx_R_local[n_R++] = i; 2951a64d13efSStefano Zampini } 2952a64d13efSStefano Zampini } 2953df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 2954df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 29556816873aSStefano Zampini 2956df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2957df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 29586816873aSStefano Zampini } 29593a50541eSStefano Zampini 29603a50541eSStefano Zampini /* Block code */ 29613a50541eSStefano Zampini vbs = 1; 29623a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 29633a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 29643a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 29653a50541eSStefano Zampini PetscInt *vary; 2966b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 2967785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 29683a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2969d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2970d3df7717SStefano 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 */ 29710e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2972d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 29733a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 29743a50541eSStefano Zampini is_blocked = PETSC_FALSE; 29753a50541eSStefano Zampini break; 29763a50541eSStefano Zampini } 29773a50541eSStefano Zampini } 2978d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2979d3df7717SStefano Zampini } else { 2980d3df7717SStefano Zampini /* Verify directly the R set */ 2981d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2982d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2983d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2984d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2985d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2986d3df7717SStefano Zampini break; 2987d3df7717SStefano Zampini } 2988d3df7717SStefano Zampini } 2989d3df7717SStefano Zampini } 2990d3df7717SStefano Zampini } 29913a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 29923a50541eSStefano Zampini vbs = bs; 29933a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 29943a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 29953a50541eSStefano Zampini } 29963a50541eSStefano Zampini } 29973a50541eSStefano Zampini } 29983a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 2999b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3000df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 300153892102SStefano Zampini 3002df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3003df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 300453892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 3005df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 300653892102SStefano Zampini } else { 30073a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 300853892102SStefano Zampini } 3009a64d13efSStefano Zampini 3010a64d13efSStefano Zampini /* print some info if requested */ 3011a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 3012a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3013a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 30141575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3015a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 3016a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 30174f1b2e48SStefano 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); 3018a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3019a64d13efSStefano Zampini } 3020a64d13efSStefano Zampini 3021a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 3022b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 30236816873aSStefano Zampini IS is_aux1,is_aux2; 30246816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 30256816873aSStefano Zampini 30263a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3027854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 3028854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 3029a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 30304641a718SStefano Zampini for (i=0; i<n_D; i++) { 30314641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 30324641a718SStefano Zampini } 3033a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3034a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 30354641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 30364641a718SStefano Zampini aux_array1[j++] = i; 3037a64d13efSStefano Zampini } 3038a64d13efSStefano Zampini } 3039a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3040a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3041a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 30424641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 30434641a718SStefano Zampini aux_array2[j++] = i; 3044a64d13efSStefano Zampini } 3045a64d13efSStefano Zampini } 3046a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3047a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 3048a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 3049a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3050a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 3051a64d13efSStefano Zampini 30528eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3053785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 3054a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 30554641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 30564641a718SStefano Zampini aux_array1[j++] = i; 3057a64d13efSStefano Zampini } 3058a64d13efSStefano Zampini } 3059a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3060a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 3061a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3062a64d13efSStefano Zampini } 30634641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 30643a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3065d62866d3SStefano Zampini } else { 3066df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 30676816873aSStefano Zampini IS tis; 30686816873aSStefano Zampini PetscInt schur_size; 30696816873aSStefano Zampini 3070df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 30716816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 3072df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 30736816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 30746816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 30756816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 30766816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 30776816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 3078d62866d3SStefano Zampini } 3079d62866d3SStefano Zampini } 3080a64d13efSStefano Zampini PetscFunctionReturn(0); 3081a64d13efSStefano Zampini } 3082a64d13efSStefano Zampini 3083304d26faSStefano Zampini 3084304d26faSStefano Zampini #undef __FUNCT__ 3085304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 3086684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 3087304d26faSStefano Zampini { 3088304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3089304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3090304d26faSStefano Zampini PC pc_temp; 3091304d26faSStefano Zampini Mat A_RR; 3092f4ddd8eeSStefano Zampini MatReuse reuse; 3093304d26faSStefano Zampini PetscScalar m_one = -1.0; 3094304d26faSStefano Zampini PetscReal value; 309504708bb6SStefano Zampini PetscInt n_D,n_R; 3096c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 3097304d26faSStefano Zampini PetscErrorCode ierr; 3098e604994aSStefano Zampini /* prefixes stuff */ 3099312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 3100e604994aSStefano Zampini size_t len; 3101304d26faSStefano Zampini 3102304d26faSStefano Zampini PetscFunctionBegin; 3103304d26faSStefano Zampini 3104e604994aSStefano Zampini /* compute prefixes */ 3105e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 3106e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 3107e604994aSStefano Zampini if (!pcbddc->current_level) { 3108e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3109e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3110e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3111e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3112e604994aSStefano Zampini } else { 3113e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 3114312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 3115e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 3116e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 3117312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 3118312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 311934d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 312034d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 3121e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3122e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3123e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 3124e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 3125e604994aSStefano Zampini } 3126e604994aSStefano Zampini 3127304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 3128684f6988SStefano Zampini if (dirichlet) { 3129d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3130450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3131b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 3132450f8f5eSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 3133450f8f5eSStefano Zampini } 3134450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 3135a3df083aSStefano Zampini Mat A_IIn; 3136a3df083aSStefano Zampini 3137a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 3138a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 3139a3df083aSStefano Zampini pcis->A_II = A_IIn; 3140a3df083aSStefano Zampini } 3141450f8f5eSStefano Zampini } 31423301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 31433301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 3144964fefecSStefano Zampini } 3145ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 3146964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 3147304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 3148304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 3149304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 3150304d26faSStefano Zampini /* default */ 3151304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 3152e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 31539577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 3154304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 31559577ea80SStefano Zampini if (issbaij) { 31569577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 31579577ea80SStefano Zampini } else { 3158304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 31599577ea80SStefano Zampini } 3160304d26faSStefano Zampini /* Allow user's customization */ 3161304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 3162304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3163304d26faSStefano Zampini } 3164d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 3165b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3166df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3167d62866d3SStefano Zampini 3168df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 3169d5574798SStefano Zampini } 3170304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3171304d26faSStefano Zampini if (!n_D) { 3172304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 3173304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3174304d26faSStefano Zampini } 3175304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 3176304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 3177304d26faSStefano Zampini /* set ksp_D into pcis data */ 3178304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 3179304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 3180304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 3181684f6988SStefano Zampini } 3182304d26faSStefano Zampini 3183304d26faSStefano Zampini /* NEUMANN PROBLEM */ 3184684f6988SStefano Zampini A_RR = 0; 3185684f6988SStefano Zampini if (neumann) { 3186d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 318704708bb6SStefano Zampini PetscInt ibs,mbs; 318804708bb6SStefano Zampini PetscBool issbaij; 318904708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3190f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 31918ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 3192f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 3193f4ddd8eeSStefano Zampini PetscInt nn_R; 319481d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 3195f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3196f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 3197f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 3198f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 3199f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3200f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3201f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 3202727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 3203f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3204f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3205f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 3206f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 3207f4ddd8eeSStefano Zampini } 3208f4ddd8eeSStefano Zampini } 3209f4ddd8eeSStefano Zampini /* last check */ 3210d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 3211f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3212f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3213f4ddd8eeSStefano Zampini } 3214f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 3215f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3216f4ddd8eeSStefano Zampini } 3217a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 3218af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 3219af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 322004708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 322104708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 322204708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 322304708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 322404708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 3225af732b37SStefano Zampini } else { 3226511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 32276816873aSStefano Zampini } 322804708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 322904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 323004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 323104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 323204708bb6SStefano Zampini } else { 3233511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 323404708bb6SStefano Zampini } 323504708bb6SStefano Zampini } 3236a00504b5SStefano Zampini /* extract A_RR */ 3237b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3238a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3239a00504b5SStefano Zampini 3240a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 324116e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3242a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 324316e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 324416e386b8SStefano Zampini } else { 3245a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 3246a00504b5SStefano Zampini } 3247a00504b5SStefano Zampini } else { 3248a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3249a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 3250a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3251a00504b5SStefano Zampini } 3252a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 3253f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 325416e386b8SStefano Zampini } 32553301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 32563301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 32576816873aSStefano Zampini } 3258f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 3259304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 3260304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 3261304d26faSStefano Zampini /* default */ 3262304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 3263e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 3264304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 32659577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 32669577ea80SStefano Zampini if (issbaij) { 32679577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 32689577ea80SStefano Zampini } else { 3269304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 32709577ea80SStefano Zampini } 3271304d26faSStefano Zampini /* Allow user's customization */ 3272304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 3273304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3274304d26faSStefano Zampini } 3275304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3276304d26faSStefano Zampini if (!n_R) { 3277304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 3278304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3279304d26faSStefano Zampini } 32805cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 3281df4d28bfSStefano Zampini /* Reuse solver if it is present */ 3282b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3283df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3284d62866d3SStefano Zampini 3285df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 3286d62866d3SStefano Zampini } 3287304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 3288304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 3289684f6988SStefano Zampini } 3290304d26faSStefano Zampini 3291684f6988SStefano Zampini if (pcbddc->dbg_flag) { 3292684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 32931575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3294684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3295684f6988SStefano Zampini } 3296c7017625SStefano Zampini 3297c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 3298c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 3299c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 3300c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 3301c7017625SStefano Zampini } 3302c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 3303c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 3304c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 3305c7017625SStefano Zampini } 3306c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 3307c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 3308c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 3309c7017625SStefano Zampini } 3310c7017625SStefano Zampini 3311c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 3312c7017625SStefano Zampini if (pcbddc->dbg_flag) { 3313684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 33140fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 33150fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 33160fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 33170fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 33180fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 3319e604994aSStefano 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); 3320c7017625SStefano Zampini if (check_corr[0]) { 3321c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 3322c7017625SStefano Zampini } 3323304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3324304d26faSStefano Zampini } 3325684f6988SStefano Zampini if (neumann) { /* Neumann */ 33260fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 33270fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 33280fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 33290fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 33300fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 3331e604994aSStefano 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); 3332c7017625SStefano Zampini if (check_corr[1]) { 3333c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 3334c7017625SStefano Zampini } 3335304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3336304d26faSStefano Zampini } 3337684f6988SStefano Zampini } 33385cbda25cSStefano Zampini /* free Neumann problem's matrix */ 33395cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3340304d26faSStefano Zampini PetscFunctionReturn(0); 3341304d26faSStefano Zampini } 3342304d26faSStefano Zampini 3343304d26faSStefano Zampini #undef __FUNCT__ 3344ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 334580677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 3346674ae819SStefano Zampini { 3347674ae819SStefano Zampini PetscErrorCode ierr; 3348674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3349be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3350b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 3351674ae819SStefano Zampini 3352674ae819SStefano Zampini PetscFunctionBegin; 3353b334f244SStefano Zampini if (!reuse_solver) { 335480677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 335520c7b377SStefano Zampini } 335680677318SStefano Zampini if (!pcbddc->switch_static) { 335780677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 335880677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 335980677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 336020c7b377SStefano Zampini } 3361b334f244SStefano Zampini if (!reuse_solver) { 336280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 336380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 336420c7b377SStefano Zampini } else { 3365df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3366be83ff47SStefano Zampini 3367df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3368df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 336920c7b377SStefano Zampini } 3370be83ff47SStefano Zampini } else { 337180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 337280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 337380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 337480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 337580677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 337680677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 337780677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 337880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 337980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3380674ae819SStefano Zampini } 3381674ae819SStefano Zampini } 3382b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 338380677318SStefano Zampini if (applytranspose) { 338480677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 338580677318SStefano Zampini } else { 338680677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 338780677318SStefano Zampini } 3388be83ff47SStefano Zampini } else { 3389df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3390be83ff47SStefano Zampini 3391be83ff47SStefano Zampini if (applytranspose) { 3392df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3393be83ff47SStefano Zampini } else { 3394df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3395be83ff47SStefano Zampini } 3396be83ff47SStefano Zampini } 339780677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 339880677318SStefano Zampini if (!pcbddc->switch_static) { 3399b334f244SStefano Zampini if (!reuse_solver) { 340080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 340180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3402be83ff47SStefano Zampini } else { 3403df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3404be83ff47SStefano Zampini 3405df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3406df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3407be83ff47SStefano Zampini } 340880677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 340980677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 341080677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 341180677318SStefano Zampini } 341280677318SStefano Zampini } else { 341380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341780677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 341880677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 341980677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 342080677318SStefano Zampini } 342180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 342280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 342380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 342480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3425674ae819SStefano Zampini } 3426674ae819SStefano Zampini PetscFunctionReturn(0); 3427674ae819SStefano Zampini } 3428674ae819SStefano Zampini 3429dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 3430674ae819SStefano Zampini #undef __FUNCT__ 3431674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 3432dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 3433674ae819SStefano Zampini { 3434674ae819SStefano Zampini PetscErrorCode ierr; 3435674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3436674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 3437674ae819SStefano Zampini const PetscScalar zero = 0.0; 3438674ae819SStefano Zampini 3439674ae819SStefano Zampini PetscFunctionBegin; 3440dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 34414fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3442dc359a40SStefano Zampini if (applytranspose) { 3443674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 34448eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 3445dc359a40SStefano Zampini } else { 3446674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 3447674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 344815aaf578SStefano Zampini } 34494fee134fSStefano Zampini } else { 34504fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 34514fee134fSStefano Zampini } 3452efc2fbd9SStefano Zampini 3453efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 34544f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3455efc2fbd9SStefano Zampini PetscScalar *array; 34564f1b2e48SStefano Zampini PetscInt j; 3457efc2fbd9SStefano Zampini 3458efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 34594f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 3460efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3461efc2fbd9SStefano Zampini } 3462efc2fbd9SStefano Zampini 346312edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 346412edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 346512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 346612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 346712edc857SStefano Zampini 34689f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 346912edc857SStefano Zampini if (pcbddc->coarse_ksp) { 347051694757SStefano Zampini Mat coarse_mat; 3471964fefecSStefano Zampini Vec rhs,sol; 347251694757SStefano Zampini MatNullSpace nullsp; 347327b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 3474964fefecSStefano Zampini 347527b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 347627b6a85dSStefano Zampini PC coarse_pc; 347727b6a85dSStefano Zampini 347827b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 347927b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 348027b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 348127b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 348227b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 348327b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 34843bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 348527b6a85dSStefano Zampini } 348627b6a85dSStefano Zampini } 3487964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 3488964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 348951694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 349051694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 349151694757SStefano Zampini if (nullsp) { 349251694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 349351694757SStefano Zampini } 349412edc857SStefano Zampini if (applytranspose) { 34951f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only) { 34961f4df5f7SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 34972701bc32SStefano Zampini } else { 3498964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 34992701bc32SStefano Zampini } 35002701bc32SStefano Zampini } else { 35011f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 35022701bc32SStefano Zampini PC coarse_pc; 35032701bc32SStefano Zampini 35042701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 35052701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 35063e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 35072701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 350812edc857SStefano Zampini } else { 3509964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 351012edc857SStefano Zampini } 35112701bc32SStefano Zampini } 35121d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 351327b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 351427b6a85dSStefano Zampini PC coarse_pc; 351527b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 351627b6a85dSStefano Zampini 351727b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 351827b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 351927b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 35203bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 352127b6a85dSStefano Zampini } 352251694757SStefano Zampini if (nullsp) { 352351694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 352451694757SStefano Zampini } 352512edc857SStefano Zampini } 3526674ae819SStefano Zampini 3527674ae819SStefano Zampini /* Local solution on R nodes */ 35284fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 352980677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 35309f00e9b4SStefano Zampini } 35319f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 35329f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 353312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3534674ae819SStefano Zampini 35354fee134fSStefano Zampini /* Sum contributions from the two levels */ 35364fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3537dc359a40SStefano Zampini if (applytranspose) { 3538dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3539dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3540dc359a40SStefano Zampini } else { 3541674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 35428eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3543dc359a40SStefano Zampini } 3544efc2fbd9SStefano Zampini /* store p0 */ 35454f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3546efc2fbd9SStefano Zampini PetscScalar *array; 35474f1b2e48SStefano Zampini PetscInt j; 3548efc2fbd9SStefano Zampini 3549efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 35504f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 3551efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3552efc2fbd9SStefano Zampini } 35534fee134fSStefano Zampini } else { /* expand the coarse solution */ 35544fee134fSStefano Zampini if (applytranspose) { 35554fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 35564fee134fSStefano Zampini } else { 35574fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 35584fee134fSStefano Zampini } 35594fee134fSStefano Zampini } 3560674ae819SStefano Zampini PetscFunctionReturn(0); 3561674ae819SStefano Zampini } 3562674ae819SStefano Zampini 3563674ae819SStefano Zampini #undef __FUNCT__ 3564674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 356512edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 3566674ae819SStefano Zampini { 3567674ae819SStefano Zampini PetscErrorCode ierr; 3568674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 356958da7f69SStefano Zampini PetscScalar *array; 357012edc857SStefano Zampini Vec from,to; 3571674ae819SStefano Zampini 3572674ae819SStefano Zampini PetscFunctionBegin; 357312edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 357412edc857SStefano Zampini from = pcbddc->coarse_vec; 357512edc857SStefano Zampini to = pcbddc->vec1_P; 357612edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 357712edc857SStefano Zampini Vec tvec; 357858da7f69SStefano Zampini 357958da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 358058da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 358112edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 358258da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 358358da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 358458da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 358512edc857SStefano Zampini } 358612edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 358712edc857SStefano Zampini from = pcbddc->vec1_P; 358812edc857SStefano Zampini to = pcbddc->coarse_vec; 358912edc857SStefano Zampini } 359012edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3591674ae819SStefano Zampini PetscFunctionReturn(0); 3592674ae819SStefano Zampini } 3593674ae819SStefano Zampini 3594674ae819SStefano Zampini #undef __FUNCT__ 3595674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 359612edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3597674ae819SStefano Zampini { 3598674ae819SStefano Zampini PetscErrorCode ierr; 3599674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 360058da7f69SStefano Zampini PetscScalar *array; 360112edc857SStefano Zampini Vec from,to; 3602674ae819SStefano Zampini 3603674ae819SStefano Zampini PetscFunctionBegin; 360412edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 360512edc857SStefano Zampini from = pcbddc->coarse_vec; 360612edc857SStefano Zampini to = pcbddc->vec1_P; 360712edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 360812edc857SStefano Zampini from = pcbddc->vec1_P; 360912edc857SStefano Zampini to = pcbddc->coarse_vec; 361012edc857SStefano Zampini } 361112edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 361212edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 361312edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 361412edc857SStefano Zampini Vec tvec; 361558da7f69SStefano Zampini 361612edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 361758da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 361858da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 361958da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 362058da7f69SStefano Zampini } 362158da7f69SStefano Zampini } else { 362258da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 362358da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 362412edc857SStefano Zampini } 362512edc857SStefano Zampini } 3626674ae819SStefano Zampini PetscFunctionReturn(0); 3627674ae819SStefano Zampini } 3628674ae819SStefano Zampini 3629984c4197SStefano Zampini /* uncomment for testing purposes */ 3630984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3631674ae819SStefano Zampini #undef __FUNCT__ 3632674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3633674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3634674ae819SStefano Zampini { 3635674ae819SStefano Zampini PetscErrorCode ierr; 3636674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3637674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3638674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3639984c4197SStefano Zampini /* one and zero */ 3640984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3641984c4197SStefano Zampini /* space to store constraints and their local indices */ 36429162d606SStefano Zampini PetscScalar *constraints_data; 36439162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 36449162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 36459162d606SStefano Zampini PetscInt *constraints_n; 3646984c4197SStefano Zampini /* iterators */ 3647b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3648984c4197SStefano Zampini /* BLAS integers */ 3649e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3650e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3651c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3652727cdba6SStefano Zampini /* reuse */ 36530e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 36540e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3655984c4197SStefano Zampini /* change of basis */ 3656b3d85658SStefano Zampini PetscBool qr_needed; 36579162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3658984c4197SStefano Zampini /* auxiliary stuff */ 365964efe560SStefano Zampini PetscInt *nnz,*is_indices; 36608a0068c3SStefano Zampini PetscInt ncc; 3661984c4197SStefano Zampini /* some quantities */ 366245a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3663a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3664984c4197SStefano Zampini 3665674ae819SStefano Zampini PetscFunctionBegin; 36668e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 36678e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 36688e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 366916909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 3670088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3671088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 36720e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 36730e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 36740e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 36750e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 36760e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3677088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3678cf5a6209SStefano Zampini 3679cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 36809162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3681cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3682cf5a6209SStefano Zampini const Vec *nearnullvecs; 3683cf5a6209SStefano Zampini Vec *localnearnullsp; 3684cf5a6209SStefano Zampini PetscScalar *array; 3685cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3686cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3687674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3688b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3689674ae819SStefano Zampini PetscScalar *work; 3690674ae819SStefano Zampini PetscReal *singular_vals; 3691674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3692674ae819SStefano Zampini PetscReal *rwork; 3693674ae819SStefano Zampini #endif 3694674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3695674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3696674ae819SStefano Zampini #else 3697964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3698964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3699674ae819SStefano Zampini #endif 3700674ae819SStefano Zampini 3701674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3702d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3703e4d548c7SStefano Zampini /* print some info */ 37041f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 3705e4d548c7SStefano Zampini PetscInt nv; 3706e4d548c7SStefano Zampini 3707e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 3708e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 3709e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3710e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3711e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3712e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 3713e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 3714e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3715e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3716e4d548c7SStefano Zampini } 3717e4d548c7SStefano Zampini 3718d06fc5fdSStefano Zampini /* free unneeded index sets */ 3719d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3720d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3721674ae819SStefano Zampini } 3722d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3723d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3724d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3725d06fc5fdSStefano Zampini } 3726d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3727d06fc5fdSStefano Zampini n_ISForEdges = 0; 3728d06fc5fdSStefano Zampini } 3729d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3730d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3731d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3732d06fc5fdSStefano Zampini } 3733d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3734d06fc5fdSStefano Zampini n_ISForFaces = 0; 3735d06fc5fdSStefano Zampini } 373670022509SStefano Zampini 3737674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3738674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3739674ae819SStefano Zampini if (nearnullsp) { 3740674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3741f4ddd8eeSStefano Zampini /* remove any stored info */ 3742f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3743f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3744f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3745f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3746f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3747473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3748f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3749f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3750f4ddd8eeSStefano Zampini } 3751984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3752984c4197SStefano Zampini nnsp_size = 0; 3753674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3754674ae819SStefano Zampini } 3755984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3756984c4197SStefano Zampini max_constraints = nnsp_size; 3757984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3758984c4197SStefano Zampini 3759674ae819SStefano Zampini /* 3760674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 37619162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 37629162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 37639162d606SStefano Zampini There can be multiple constraints per connected component 3764674ae819SStefano Zampini */ 3765674ae819SStefano Zampini n_vertices = 0; 3766674ae819SStefano Zampini if (ISForVertices) { 3767674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3768674ae819SStefano Zampini } 37699162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 37709162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 37719162d606SStefano Zampini 37729162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 37739162d606SStefano Zampini total_counts *= max_constraints; 3774674ae819SStefano Zampini total_counts += n_vertices; 37754641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 37769162d606SStefano Zampini 3777674ae819SStefano Zampini total_counts = 0; 3778674ae819SStefano Zampini max_size_of_constraint = 0; 3779674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 37809162d606SStefano Zampini IS used_is; 3781674ae819SStefano Zampini if (i<n_ISForEdges) { 37829162d606SStefano Zampini used_is = ISForEdges[i]; 3783674ae819SStefano Zampini } else { 37849162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3785674ae819SStefano Zampini } 37869162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3787674ae819SStefano Zampini total_counts += j; 3788674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3789674ae819SStefano Zampini } 37909162d606SStefano 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); 37919162d606SStefano Zampini 3792984c4197SStefano Zampini /* get local part of global near null space vectors */ 3793785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3794984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3795984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3796e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3797e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3798984c4197SStefano Zampini } 3799674ae819SStefano Zampini 3800242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3801242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3802a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3803242a89d7SStefano Zampini 3804984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3805a773dcb8SStefano Zampini if (!skip_lapack) { 3806674ae819SStefano Zampini PetscScalar temp_work; 3807911cabfeSStefano Zampini 3808674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3809984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3810785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3811785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3812785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3813674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3814785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3815674ae819SStefano Zampini #endif 3816674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3817c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3818c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3819674ae819SStefano Zampini lwork = -1; 3820674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3821674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3822c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3823674ae819SStefano Zampini #else 3824c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3825674ae819SStefano Zampini #endif 3826674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3827984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3828674ae819SStefano Zampini #else /* on missing GESVD */ 3829674ae819SStefano Zampini /* SVD */ 3830674ae819SStefano Zampini PetscInt max_n,min_n; 3831674ae819SStefano Zampini max_n = max_size_of_constraint; 3832984c4197SStefano Zampini min_n = max_constraints; 3833984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3834674ae819SStefano Zampini min_n = max_size_of_constraint; 3835984c4197SStefano Zampini max_n = max_constraints; 3836674ae819SStefano Zampini } 3837785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3838674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3839785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3840674ae819SStefano Zampini #endif 3841674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3842674ae819SStefano Zampini lwork = -1; 3843e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3844e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3845b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3846674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3847674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 38489162d606SStefano 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)); 3849674ae819SStefano Zampini #else 38509162d606SStefano 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)); 3851674ae819SStefano Zampini #endif 3852674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3853984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3854984c4197SStefano Zampini #endif /* on missing GESVD */ 3855674ae819SStefano Zampini /* Allocate optimal workspace */ 3856674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3857854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3858674ae819SStefano Zampini } 3859674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3860674ae819SStefano Zampini total_counts = 0; 38619162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 38629162d606SStefano Zampini constraints_data_ptr[0] = 0; 3863674ae819SStefano Zampini /* vertices */ 38649162d606SStefano Zampini if (n_vertices) { 3865674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 38669162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3867674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 38689162d606SStefano Zampini constraints_n[total_counts] = 1; 38699162d606SStefano Zampini constraints_data[total_counts] = 1.0; 38709162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 38719162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3872674ae819SStefano Zampini total_counts++; 3873674ae819SStefano Zampini } 3874674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3875674ae819SStefano Zampini n_vertices = total_counts; 3876674ae819SStefano Zampini } 3877984c4197SStefano Zampini 3878674ae819SStefano Zampini /* edges and faces */ 38799162d606SStefano Zampini total_counts_cc = total_counts; 3880911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 38819162d606SStefano Zampini IS used_is; 38829162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 38839162d606SStefano Zampini 3884911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 38859162d606SStefano Zampini used_is = ISForEdges[ncc]; 3886984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3887674ae819SStefano Zampini } else { 38889162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3889984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3890674ae819SStefano Zampini } 3891674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 38929162d606SStefano Zampini 38939162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 38949162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3895984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3896984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3897674ae819SStefano Zampini if (nnsp_has_cnst) { 38985b08dc53SStefano Zampini PetscScalar quad_value; 38999162d606SStefano Zampini 39009162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 39019162d606SStefano Zampini idxs_copied = PETSC_TRUE; 39029162d606SStefano Zampini 3903a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3904674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3905a773dcb8SStefano Zampini } else { 3906a773dcb8SStefano Zampini quad_value = 1.0; 3907a773dcb8SStefano Zampini } 3908674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 39099162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3910674ae819SStefano Zampini } 39119162d606SStefano Zampini temp_constraints++; 3912674ae819SStefano Zampini total_counts++; 3913674ae819SStefano Zampini } 3914674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3915984c4197SStefano Zampini PetscReal real_value; 39169162d606SStefano Zampini PetscScalar *ptr_to_data; 39179162d606SStefano Zampini 3918984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 39199162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3920674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 39219162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3922674ae819SStefano Zampini } 3923984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3924984c4197SStefano Zampini /* check if array is null on the connected component */ 3925e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39269162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 39275b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3928674ae819SStefano Zampini temp_constraints++; 3929674ae819SStefano Zampini total_counts++; 39309162d606SStefano Zampini if (!idxs_copied) { 39319162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 39329162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3933674ae819SStefano Zampini } 3934674ae819SStefano Zampini } 39359162d606SStefano Zampini } 39369162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 393745a1bb75SStefano Zampini valid_constraints = temp_constraints; 3938eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3939a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 39409162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 39419162d606SStefano Zampini 39429162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3943a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39449162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3945a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 39469162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3947a773dcb8SStefano Zampini } else { /* perform SVD */ 3948984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 39499162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3950674ae819SStefano Zampini 3951674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3952984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3953984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3954984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3955984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3956984c4197SStefano Zampini from that computed using LAPACKgesvd 3957984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3958984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3959984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3960674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3961e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3962984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3963674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3964674ae819SStefano Zampini for (k=0;k<j+1;k++) { 39659162d606SStefano 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)); 3966674ae819SStefano Zampini } 3967674ae819SStefano Zampini } 3968e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3969e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3970e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3971674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3972c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3973674ae819SStefano Zampini #else 3974c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3975674ae819SStefano Zampini #endif 3976674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3977984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3978984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3979674ae819SStefano Zampini j = 0; 3980984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3981674ae819SStefano Zampini total_counts = total_counts-j; 398245a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3983e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3984c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3985c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3986c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3987c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3988c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3989c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3990674ae819SStefano Zampini if (j<temp_constraints) { 3991984c4197SStefano Zampini PetscInt ii; 3992984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3993674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39949162d606SStefano 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)); 3995674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3996984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3997674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 39989162d606SStefano 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]; 3999674ae819SStefano Zampini } 4000674ae819SStefano Zampini } 4001674ae819SStefano Zampini } 4002674ae819SStefano Zampini #else /* on missing GESVD */ 4003e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 4004e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 4005b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4006674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4007674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 40089162d606SStefano 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)); 4009674ae819SStefano Zampini #else 40109162d606SStefano 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)); 4011674ae819SStefano Zampini #endif 4012984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 4013674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4014984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 4015e310c8b4SStefano Zampini k = temp_constraints; 4016e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 4017674ae819SStefano Zampini j = 0; 4018e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 401945a1bb75SStefano Zampini valid_constraints = k-j; 4020911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 4021984c4197SStefano Zampini #endif /* on missing GESVD */ 4022674ae819SStefano Zampini } 4023a773dcb8SStefano Zampini } 40249162d606SStefano Zampini /* update pointers information */ 40259162d606SStefano Zampini if (valid_constraints) { 40269162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 40279162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 40289162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 40299162d606SStefano Zampini /* set change_of_basis flag */ 403045a1bb75SStefano Zampini if (boolforchange) { 4031b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 40329162d606SStefano Zampini } 4033b3d85658SStefano Zampini total_counts_cc++; 403445a1bb75SStefano Zampini } 403545a1bb75SStefano Zampini } 4036984c4197SStefano Zampini /* free workspace */ 40378f1c130eSStefano Zampini if (!skip_lapack) { 4038984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4039984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4040984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 4041984c4197SStefano Zampini #endif 4042984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 4043984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4044984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 4045984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 4046984c4197SStefano Zampini #endif 4047984c4197SStefano Zampini } 4048984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4049984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 4050984c4197SStefano Zampini } 4051984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 4052cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 4053cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4054cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4055cf5a6209SStefano Zampini } 4056cf5a6209SStefano Zampini if (n_ISForFaces) { 4057cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4058cf5a6209SStefano Zampini } 4059cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4060cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4061cf5a6209SStefano Zampini } 4062cf5a6209SStefano Zampini if (n_ISForEdges) { 4063cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4064cf5a6209SStefano Zampini } 4065cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 406608122e43SStefano Zampini } else { 406708122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4068984c4197SStefano Zampini 406908122e43SStefano Zampini total_counts = 0; 407008122e43SStefano Zampini n_vertices = 0; 4071d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 4072d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 407308122e43SStefano Zampini } 407408122e43SStefano Zampini max_constraints = 0; 40759162d606SStefano Zampini total_counts_cc = 0; 407608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 407708122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 40789162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 407908122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 408008122e43SStefano Zampini } 40819162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 40829162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 40839162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 40849162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 408574d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 40869162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 40879162d606SStefano Zampini total_counts_cc = 0; 40889162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 40899162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 40909162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 409108122e43SStefano Zampini } 409208122e43SStefano Zampini } 40939162d606SStefano Zampini #if 0 40949162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 40959162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 40969162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 40979162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 40989162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 40999162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 41009162d606SStefano Zampini } 41019162d606SStefano Zampini printf("\n"); 41029162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 41039162d606SStefano Zampini } 41041b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 41058bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 41061b968477SStefano Zampini } 41071b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 41088bec7fa6SStefano 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]); 41091b968477SStefano Zampini } 411008122e43SStefano Zampini #endif 411108122e43SStefano Zampini 41128bec7fa6SStefano Zampini max_size_of_constraint = 0; 41139162d606SStefano 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]); 41149162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 411508122e43SStefano Zampini /* Change of basis */ 4116b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 411708122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 411808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 411908122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 4120b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 412108122e43SStefano Zampini } 412208122e43SStefano Zampini } 412308122e43SStefano Zampini } 412408122e43SStefano Zampini } 4125984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 41264f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 412708122e43SStefano Zampini 41289162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 41299162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 41306c4ed002SBarry Smith if (i != constraints_idxs_ptr[total_counts_cc]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %D != %D\n",constraints_idxs_ptr[total_counts_cc],i); 4131674ae819SStefano Zampini 4132674ae819SStefano Zampini /* Create constraint matrix */ 4133674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 413416f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 4135984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 4136984c4197SStefano Zampini 4137984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 4138a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 4139a717540cSStefano Zampini qr_needed = PETSC_FALSE; 414074d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 4141984c4197SStefano Zampini total_primal_vertices=0; 4142b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 41439162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 41449162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 414572b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 41469162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 4147b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 414864efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 41499162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 41509162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 4151a717540cSStefano Zampini } 4152b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 415391af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 4154a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 4155a717540cSStefano Zampini qr_needed = PETSC_TRUE; 4156a717540cSStefano Zampini } 4157fa434743SStefano Zampini } else { 4158b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 4159fa434743SStefano Zampini } 4160a717540cSStefano Zampini } 4161b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 4162b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 4163674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 416470022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4165b3d85658SStefano Zampini 41664f1b2e48SStefano 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); 41670e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 41680e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 4169984c4197SStefano Zampini 4170984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 417174d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 4172785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 4173984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 417474d5cdf7SStefano Zampini 4175984c4197SStefano Zampini j = total_primal_vertices; 417674d5cdf7SStefano Zampini total_counts = total_primal_vertices; 4177b3d85658SStefano Zampini cum = total_primal_vertices; 41789162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 41794641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 4180b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 4181b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 4182b3d85658SStefano Zampini cum++; 41839162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 418474d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 418574d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 418674d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 418774d5cdf7SStefano Zampini } 41889162d606SStefano Zampini j += constraints_n[i]; 4189674ae819SStefano Zampini } 4190674ae819SStefano Zampini } 4191674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 4192674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 4193088faed8SStefano Zampini 4194674ae819SStefano Zampini /* set values in constraint matrix */ 4195984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 41960e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4197674ae819SStefano Zampini } 4198984c4197SStefano Zampini total_counts = total_primal_vertices; 41999162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 42004641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 42019162d606SStefano Zampini PetscInt *cols; 42029162d606SStefano Zampini 42039162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 42049162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 42059162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 42069162d606SStefano Zampini PetscInt row = total_counts+k; 42079162d606SStefano Zampini PetscScalar *vals; 42089162d606SStefano Zampini 42099162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 42109162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 42119162d606SStefano Zampini } 42129162d606SStefano Zampini total_counts += constraints_n[i]; 4213674ae819SStefano Zampini } 4214674ae819SStefano Zampini } 4215674ae819SStefano Zampini /* assembling */ 4216674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4217674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4218088faed8SStefano Zampini 4219984c4197SStefano Zampini /* 42206a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4221984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 4222f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 4223984c4197SStefano Zampini */ 4224674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 4225674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 4226026de310SStefano Zampini /* dual and primal dofs on a single cc */ 4227984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 4228984c4197SStefano Zampini /* working stuff for GEQRF */ 422981d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 4230984c4197SStefano Zampini PetscBLASInt lqr_work; 4231984c4197SStefano Zampini /* working stuff for UNGQR */ 4232984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 4233984c4197SStefano Zampini PetscBLASInt lgqr_work; 4234984c4197SStefano Zampini /* working stuff for TRTRS */ 4235984c4197SStefano Zampini PetscScalar *trs_rhs; 42363f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 4237984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 4238984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 4239984c4197SStefano Zampini PetscScalar *start_vals; 4240984c4197SStefano Zampini /* working stuff for values insertion */ 42414641a718SStefano Zampini PetscBT is_primal; 424264efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 4243906d46d4SStefano Zampini /* matrix sizes */ 4244906d46d4SStefano Zampini PetscInt global_size,local_size; 4245906d46d4SStefano Zampini /* temporary change of basis */ 4246906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 4247cf5a6209SStefano Zampini /* extra space for debugging */ 4248cf5a6209SStefano Zampini PetscScalar *dbg_work; 4249984c4197SStefano Zampini 4250906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 4251906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 425216f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 4253bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 4254906d46d4SStefano Zampini /* nonzeros for local mat */ 4255bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 42561dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4257bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 42581dd7afcfSStefano Zampini } else { 42591dd7afcfSStefano Zampini const PetscInt *ii; 42601dd7afcfSStefano Zampini PetscInt n; 42611dd7afcfSStefano Zampini PetscBool flg_row; 42621dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 42631dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 42641dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 42651dd7afcfSStefano Zampini } 42669162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 4267a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 42689162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 4269a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 42709162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 4271a717540cSStefano Zampini } else { 42729162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 42739162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 4274a717540cSStefano Zampini } 4275a717540cSStefano Zampini } 4276a717540cSStefano Zampini } 4277906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 4278bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 42791dd7afcfSStefano Zampini /* Set interior change in the matrix */ 42801dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4281bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 4282906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 4283a717540cSStefano Zampini } 42841dd7afcfSStefano Zampini } else { 42851dd7afcfSStefano Zampini const PetscInt *ii,*jj; 42861dd7afcfSStefano Zampini PetscScalar *aa; 42871dd7afcfSStefano Zampini PetscInt n; 42881dd7afcfSStefano Zampini PetscBool flg_row; 42891dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 42901dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 42911dd7afcfSStefano Zampini for (i=0;i<n;i++) { 42921dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 42931dd7afcfSStefano Zampini } 42941dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 42951dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 42961dd7afcfSStefano Zampini } 4297a717540cSStefano Zampini 4298a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4299a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4300a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4301a717540cSStefano Zampini } 4302a717540cSStefano Zampini 4303a717540cSStefano Zampini 4304a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 4305a717540cSStefano Zampini /* 4306a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 4307a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 4308a717540cSStefano Zampini 4309a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 4310a717540cSStefano Zampini 4311a6b551f4SStefano 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) 4312a6b551f4SStefano Zampini 4313a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 4314a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 4315a717540cSStefano Zampini | ... | 4316a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 4317a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 4318a717540cSStefano Zampini 4319a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 4320a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 4321a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 4322a6b551f4SStefano Zampini 4323a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 4324a717540cSStefano Zampini */ 4325a717540cSStefano Zampini if (qr_needed) { 4326984c4197SStefano Zampini /* space to store Q */ 4327854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 4328984c4197SStefano Zampini /* first we issue queries for optimal work */ 43293f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 43303f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 43313f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4332984c4197SStefano Zampini lqr_work = -1; 43333f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 4334984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 4335984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 4336785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 4337984c4197SStefano Zampini lgqr_work = -1; 43383f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 43393f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 43403f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 43413f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 43423f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 43433f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 4344984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 4345984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 4346785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 4347984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 4348785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 4349984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 4350785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 4351a717540cSStefano Zampini /* allocating workspace for check */ 4352a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4353cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 4354a717540cSStefano Zampini } 4355a717540cSStefano Zampini } 4356984c4197SStefano Zampini /* array to store whether a node is primal or not */ 43574641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 4358473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 43590e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 43606c4ed002SBarry Smith if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %D != %D\n",total_primal_vertices,i); 436139e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 436239e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 436339e2fb2aSStefano Zampini } 436439e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 4365984c4197SStefano Zampini 4366a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 43679162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 43689162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 43694641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 4370984c4197SStefano Zampini /* get constraint info */ 43719162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 4372984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 4373984c4197SStefano Zampini 4374984c4197SStefano Zampini if (pcbddc->dbg_flag) { 43759162d606SStefano 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); 4376674ae819SStefano Zampini } 4377984c4197SStefano Zampini 4378fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 4379a717540cSStefano Zampini 4380a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 4381a717540cSStefano Zampini if (pcbddc->dbg_flag) { 43829162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4383a717540cSStefano Zampini } 4384984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 43859162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4386984c4197SStefano Zampini 4387984c4197SStefano Zampini /* compute QR decomposition of constraints */ 43883f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 43893f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 43903f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4391674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43923f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 4393984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 4394674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4395984c4197SStefano Zampini 4396984c4197SStefano Zampini /* explictly compute R^-T */ 4397984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 4398984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 43993f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 44003f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 44013f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 44023f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 4403984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 44043f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 4405984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 4406984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4407984c4197SStefano Zampini 4408a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 44093f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 44103f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 44113f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 44123f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4413984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 44143f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 4415984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 4416984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4417984c4197SStefano Zampini 4418984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 4419984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 4420984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 44213f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 44223f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 44233f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 44243f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 44253f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 44263f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 4427984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 44289162d606SStefano 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)); 4429984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 44309162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4431984c4197SStefano Zampini 4432984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 44339162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 4434984c4197SStefano Zampini /* insert cols for primal dofs */ 4435984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 4436984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 44379162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4438906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4439984c4197SStefano Zampini } 4440984c4197SStefano Zampini /* insert cols for dual dofs */ 4441984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 44429162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 4443984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 44449162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4445906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4446984c4197SStefano Zampini j++; 4447674ae819SStefano Zampini } 4448674ae819SStefano Zampini } 4449984c4197SStefano Zampini 4450984c4197SStefano Zampini /* check change of basis */ 4451984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4452984c4197SStefano Zampini PetscInt ii,jj; 4453984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 4454c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 4455c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4456c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 4457c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4458c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 4459c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 4460984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4461cf5a6209SStefano 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)); 4462984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4463984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4464984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4465cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 4466cf5a6209SStefano 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; 4467674ae819SStefano Zampini } 4468674ae819SStefano Zampini } 4469984c4197SStefano Zampini if (!valid_qr) { 447022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 4471984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4472984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4473cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 4474cf5a6209SStefano 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])); 4475674ae819SStefano Zampini } 4476cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 4477cf5a6209SStefano 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])); 4478984c4197SStefano Zampini } 4479984c4197SStefano Zampini } 4480984c4197SStefano Zampini } 4481674ae819SStefano Zampini } else { 448222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 4483674ae819SStefano Zampini } 4484674ae819SStefano Zampini } 4485a717540cSStefano Zampini } else { /* simple transformation block */ 4486a717540cSStefano Zampini PetscInt row,col; 4487a6b551f4SStefano Zampini PetscScalar val,norm; 4488a6b551f4SStefano Zampini 4489a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 44909162d606SStefano 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)); 4491a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 44929162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 44939162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4494bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 44959162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 4496906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 44979162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 4498a717540cSStefano Zampini } else { 4499a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 45009162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4501a717540cSStefano Zampini if (row != col) { 45029162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 4503a717540cSStefano Zampini } else { 45049162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 4505a717540cSStefano Zampini } 4506906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 4507a717540cSStefano Zampini } 4508a717540cSStefano Zampini } 4509a717540cSStefano Zampini } 451098a51de6SStefano Zampini if (pcbddc->dbg_flag) { 451122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 4512a717540cSStefano Zampini } 4513674ae819SStefano Zampini } 4514984c4197SStefano Zampini } else { 4515984c4197SStefano Zampini if (pcbddc->dbg_flag) { 45169162d606SStefano 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); 4517674ae819SStefano Zampini } 4518674ae819SStefano Zampini } 4519674ae819SStefano Zampini } 4520a717540cSStefano Zampini 4521a717540cSStefano Zampini /* free workspace */ 4522a717540cSStefano Zampini if (qr_needed) { 4523984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4524cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 4525984c4197SStefano Zampini } 4526984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 4527984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 4528984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 4529984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 4530984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 4531674ae819SStefano Zampini } 4532a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 4533906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4534906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4535906d46d4SStefano Zampini 4536906d46d4SStefano Zampini /* assembling of global change of variable */ 453788c03ad3SStefano Zampini if (!pcbddc->fake_change) { 4538bbb9e6c6SStefano Zampini Mat tmat; 453916f15bc4SStefano Zampini PetscInt bs; 454016f15bc4SStefano Zampini 4541906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4542906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4543bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4544bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 4545bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4546bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 454716f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 454816f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 4549906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4550bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 4551bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4552bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4553bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4554bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4555e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4556e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4557bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 4558bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 455988c03ad3SStefano Zampini 4560906d46d4SStefano Zampini /* check */ 4561906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4562906d46d4SStefano Zampini PetscReal error; 4563906d46d4SStefano Zampini Vec x,x_change; 4564906d46d4SStefano Zampini 4565906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 4566906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 4567906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 4568906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 4569e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4570e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4571bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4572e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4573e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4574906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4575906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4576906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4577906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4578bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4579906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4580906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4581906d46d4SStefano Zampini } 4582b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4583b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4584b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4585bf3a8328SStefano Zampini 4586bf3a8328SStefano Zampini if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) { 4587bf3a8328SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints");CHKERRQ(ierr); 4588bf3a8328SStefano Zampini } 4589b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 4590ac632422SStefano Zampini Mat S_new,tmat; 4591bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 4592bbb9e6c6SStefano Zampini 4593bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 45946816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4595bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4596bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 4597bf3a8328SStefano Zampini IS is_V; 4598b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4599b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4600b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4601b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4602b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4603bf3a8328SStefano Zampini } 4604bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4605ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4606b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4607ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4608bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4609bf3a8328SStefano Zampini const PetscScalar *array; 4610bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 4611bf3a8328SStefano Zampini PetscInt i,n_V; 4612bf3a8328SStefano Zampini 4613b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4614b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4615b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4616b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4617b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4618b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4619b087196eSStefano Zampini PetscScalar val; 4620b087196eSStefano Zampini PetscInt idx; 4621b087196eSStefano Zampini 4622b087196eSStefano Zampini idx = idxs_V[i]; 4623b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4624b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4625b087196eSStefano Zampini } 4626b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4627b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4628bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4629bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4630bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4631bf3a8328SStefano Zampini } 4632ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4633ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4634ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4635ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4636b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4637ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4638bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4639b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4640bf3a8328SStefano Zampini } 4641ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4642ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4643ac632422SStefano Zampini } 4644b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 464588c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4646b96c3477SStefano Zampini } 4647c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 4648b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 4649c9db6a07SStefano Zampini PetscInt i; 4650c9db6a07SStefano Zampini 4651c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4652c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 4653c9db6a07SStefano Zampini } 4654c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 4655c9db6a07SStefano Zampini } 4656b96c3477SStefano Zampini } 465716909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 465816909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 465916909a7fSStefano Zampini } else { 4660906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 466116909a7fSStefano Zampini } 46621dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 466327b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 466472b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 466572b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 466672b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 466772b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 466872b8c272SStefano Zampini } 46691dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 467027b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 4671b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4672b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4673906d46d4SStefano Zampini } else { 46741dd7afcfSStefano Zampini Mat benign_global = NULL; 467527b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 46761dd7afcfSStefano Zampini Mat tmat; 46771dd7afcfSStefano Zampini 46781dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 46791dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 46801dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 46811dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 46821dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 46831dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 46841dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46851dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46861dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 46871dd7afcfSStefano Zampini if (pcbddc->benign_change) { 46881dd7afcfSStefano Zampini Mat M; 46891dd7afcfSStefano Zampini 46901dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 46911dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 46921dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 46931dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4694906d46d4SStefano Zampini } else { 46951dd7afcfSStefano Zampini Mat eye; 46961dd7afcfSStefano Zampini PetscScalar *array; 46971dd7afcfSStefano Zampini 46981dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 46991dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 47001dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 47011dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 4702906d46d4SStefano Zampini } 47031dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 47041dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47051dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47061dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 47071dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 47081dd7afcfSStefano Zampini } 47091dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 47101dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 47111dd7afcfSStefano Zampini } 47121dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 47131dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 47141dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 471527b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 47161dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 47171dd7afcfSStefano Zampini } 47181dd7afcfSStefano Zampini } 471916909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 472016909a7fSStefano Zampini IS is_global; 472116909a7fSStefano Zampini const PetscInt *gidxs; 472216909a7fSStefano Zampini 472316909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 472416909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 472516909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 472616909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 472716909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 472816909a7fSStefano Zampini } 47291dd7afcfSStefano Zampini } 47301dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 47311dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 4732b9b85e73SStefano Zampini } 4733a717540cSStefano Zampini 473472b8c272SStefano Zampini if (!pcbddc->fake_change) { 47354f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 47364f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 47374f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 47384f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4739019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4740019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4741019a44ceSStefano Zampini pcbddc->local_primal_size++; 4742019a44ceSStefano Zampini } 4743019a44ceSStefano Zampini 4744019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4745727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4746727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 47479f47a83aSStefano 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); 4748c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 47490e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 47509f47a83aSStefano 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); 4751727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4752727cdba6SStefano Zampini } 47530e6343abSStefano Zampini } 4754727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4755b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 475672b8c272SStefano Zampini } 475772b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4758727cdba6SStefano Zampini 4759a717540cSStefano Zampini /* flush dbg viewer */ 4760b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4761b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4762b8ffe317SStefano Zampini } 4763a717540cSStefano Zampini 4764e310c8b4SStefano Zampini /* free workspace */ 4765a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 47664641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 476708122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 47689162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 47699162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 477008122e43SStefano Zampini } else { 47719162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 47729162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 47739162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 477408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 477508122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 47769162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 47779162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 477808122e43SStefano Zampini } 4779674ae819SStefano Zampini PetscFunctionReturn(0); 4780674ae819SStefano Zampini } 4781674ae819SStefano Zampini 4782674ae819SStefano Zampini #undef __FUNCT__ 4783674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4784674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4785674ae819SStefano Zampini { 4786674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4787674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4788674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 478914f95afaSStefano Zampini PetscInt ierr,i,N; 4790674ae819SStefano Zampini 4791674ae819SStefano Zampini PetscFunctionBegin; 47928e61c736SStefano Zampini /* Reset previously computed graph */ 47938e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4794674ae819SStefano Zampini /* Init local Graph struct */ 47957fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 47963bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4797674ae819SStefano Zampini 4798575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 47995099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 48005099eff2SStefano 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); 4801575ad6abSStefano Zampini } 48029577ea80SStefano Zampini 4803674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 4804d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 48054d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 48064d379d7bSStefano Zampini PetscInt nvtxs; 4807e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4808674ae819SStefano Zampini 48092fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 48102fffb893SStefano Zampini if (flg_row) { 48114d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4812b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 48132fffb893SStefano Zampini } 48142fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4815674ae819SStefano Zampini } 48169b28b941SStefano Zampini if (pcbddc->dbg_flag) { 48179b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4818674ae819SStefano Zampini } 4819674ae819SStefano Zampini 4820674ae819SStefano Zampini /* Setup of Graph */ 48214b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 482214f95afaSStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,pcbddc->vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 4823674ae819SStefano Zampini 48244f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 48254f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 48264f1b2e48SStefano Zampini PetscInt *local_subs; 48274f1b2e48SStefano Zampini 48284f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 48294f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 48304f1b2e48SStefano Zampini const PetscInt *idxs; 48314f1b2e48SStefano Zampini PetscInt nl,j; 48324f1b2e48SStefano Zampini 48334f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 48344f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 48354f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 48364f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 48374f1b2e48SStefano Zampini } 48384f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 48394f1b2e48SStefano Zampini } 48404f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 48414f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 48424f1b2e48SStefano Zampini } 48434f1b2e48SStefano Zampini 4844674ae819SStefano Zampini /* Graph's connected components analysis */ 4845674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4846674ae819SStefano Zampini PetscFunctionReturn(0); 4847674ae819SStefano Zampini } 4848674ae819SStefano Zampini 4849dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 4850674ae819SStefano Zampini #undef __FUNCT__ 4851674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 4852dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 4853674ae819SStefano Zampini { 4854dc456d91SStefano Zampini PetscSF sf; 4855dc456d91SStefano Zampini PetscLayout map; 4856dc456d91SStefano Zampini const PetscInt *idxs; 4857dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4858dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4859dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4860dc456d91SStefano Zampini PetscMPIInt commsize; 4861674ae819SStefano Zampini PetscBool first_found; 4862674ae819SStefano Zampini PetscErrorCode ierr; 4863674ae819SStefano Zampini 4864674ae819SStefano Zampini PetscFunctionBegin; 4865dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4866dc456d91SStefano Zampini if (subset_mult) { 4867dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4868dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4869dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4870674ae819SStefano Zampini } 4871dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4872dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4873dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4874dc456d91SStefano Zampini for (i=0;i<n;i++) { 4875dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4876dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4877674ae819SStefano Zampini } 4878dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4879b2566f29SBarry Smith ierr = MPIU_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4880dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4881dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4882dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4883dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4884dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4885dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4886dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4887dc456d91SStefano Zampini 4888dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4889dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4890dc456d91SStefano Zampini if (subset_mult) { 4891dc456d91SStefano Zampini const PetscInt* idxs_mult; 4892dc456d91SStefano Zampini 4893dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4894dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4895dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4896674ae819SStefano Zampini } else { 4897dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4898674ae819SStefano Zampini } 4899dc456d91SStefano Zampini /* local size of new subset */ 4900dc456d91SStefano Zampini n_n = 0; 4901dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4902dc456d91SStefano Zampini 4903dc456d91SStefano Zampini /* global indexes in layout */ 4904dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4905dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4906dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4907dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4908dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4909dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4910dc456d91SStefano Zampini 4911dc456d91SStefano Zampini /* reduce from leaves to roots */ 4912dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 491364a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 491464a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4915dc456d91SStefano Zampini 4916dc456d91SStefano Zampini /* count indexes in local part of layout */ 4917674ae819SStefano Zampini nlocals = 0; 4918674ae819SStefano Zampini first_index = -1; 4919674ae819SStefano Zampini first_found = PETSC_FALSE; 4920dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4921dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4922674ae819SStefano Zampini first_found = PETSC_TRUE; 4923674ae819SStefano Zampini first_index = i; 4924674ae819SStefano Zampini } 4925dc456d91SStefano Zampini nlocals += root_data[i]; 4926674ae819SStefano Zampini } 4927dc456d91SStefano Zampini 4928dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 49295fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4930dc456d91SStefano Zampini start = 0; 493164a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 49325fa240b1SStefano Zampini #else 493364a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 49345fa240b1SStefano Zampini start = start-nlocals; 49355fa240b1SStefano Zampini #endif 49365fa240b1SStefano Zampini 4937dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4938dc456d91SStefano Zampini *N_n = start + nlocals; 4939dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4940dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4941674ae819SStefano Zampini } 49425fa240b1SStefano Zampini 49435fa240b1SStefano Zampini /* adapt root data with cumulative */ 4944674ae819SStefano Zampini if (first_found) { 4945dc456d91SStefano Zampini PetscInt old_index; 4946dc456d91SStefano Zampini 4947dc456d91SStefano Zampini root_data[first_index] += start; 4948674ae819SStefano Zampini old_index = first_index; 4949dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4950dc456d91SStefano Zampini if (root_data[i]) { 4951dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4952674ae819SStefano Zampini old_index = i; 4953674ae819SStefano Zampini } 4954674ae819SStefano Zampini } 4955674ae819SStefano Zampini } 4956dc456d91SStefano Zampini 4957dc456d91SStefano Zampini /* from roots to leaves */ 4958dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4959dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4960dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4961dc456d91SStefano Zampini 4962dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4963dc456d91SStefano Zampini if (subset_mult) { 4964dc456d91SStefano Zampini const PetscInt* idxs_mult; 4965dc456d91SStefano Zampini PetscInt cum; 4966dc456d91SStefano Zampini 4967dc456d91SStefano Zampini cum = 0; 4968dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4969dc456d91SStefano Zampini for (i=0;i<n;i++) { 4970dc456d91SStefano Zampini PetscInt j; 4971dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4972674ae819SStefano Zampini } 4973dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4974674ae819SStefano Zampini } else { 4975dc456d91SStefano Zampini for (i=0;i<n;i++) { 4976dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4977674ae819SStefano Zampini } 4978674ae819SStefano Zampini } 4979dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4980dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4981674ae819SStefano Zampini PetscFunctionReturn(0); 4982674ae819SStefano Zampini } 49839a7d3425SStefano Zampini 4984669cc0f4SStefano Zampini /* this implements stabilized Gram-Schmidt */ 49859a7d3425SStefano Zampini #undef __FUNCT__ 49869a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 49879a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 49889a7d3425SStefano Zampini { 49899a7d3425SStefano Zampini PetscInt i,j; 49909a7d3425SStefano Zampini PetscScalar *alphas; 49919a7d3425SStefano Zampini PetscErrorCode ierr; 49929a7d3425SStefano Zampini 49939a7d3425SStefano Zampini PetscFunctionBegin; 4994785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 49959a7d3425SStefano Zampini for (i=0;i<n;i++) { 49969a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 4997669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 4998669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 4999669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 50009a7d3425SStefano Zampini } 50019a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 50029a7d3425SStefano Zampini PetscFunctionReturn(0); 50039a7d3425SStefano Zampini } 50049a7d3425SStefano Zampini 5005e7931f94SStefano Zampini #undef __FUNCT__ 500670cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 500757de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 5008e7931f94SStefano Zampini { 500957de7509SStefano Zampini Mat A; 5010e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 5011e7931f94SStefano Zampini PetscMPIInt size,rank,color; 501252e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 501352e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 501427b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 501557de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 501627b6a85dSStefano Zampini PetscInt xadj_count, *count; 501727b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 501827b6a85dSStefano Zampini PetscSubcomm psubcomm; 501927b6a85dSStefano Zampini MPI_Comm subcomm; 502052e5ac9dSStefano Zampini PetscErrorCode ierr; 5021a57a6d2fSStefano Zampini 5022e7931f94SStefano Zampini PetscFunctionBegin; 502357de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 502457de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 502557de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 502657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 502757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 502857de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 502957de7509SStefano Zampini 503057de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 503157de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 503257de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 503357de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 503457de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 503557de7509SStefano Zampini im_active = !!(n); 503657de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 503757de7509SStefano Zampini void_procs = size - active_procs; 503857de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 503957de7509SStefano Zampini if (void_procs) { 504057de7509SStefano Zampini PetscInt ncand; 504157de7509SStefano Zampini 504257de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 504357de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 504457de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 504557de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 504657de7509SStefano Zampini if (!procs_candidates[i]) { 504757de7509SStefano Zampini procs_candidates[ncand++] = i; 504857de7509SStefano Zampini } 504957de7509SStefano Zampini } 505057de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 505157de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 505257de7509SStefano Zampini } 505357de7509SStefano Zampini 505457de7509SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix */ 505557de7509SStefano Zampini if (active_procs < *n_subdomains) { 505657de7509SStefano Zampini PetscInt issize,isidx; 505757de7509SStefano Zampini if (im_active) { 505857de7509SStefano Zampini issize = 1; 505957de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 506057de7509SStefano Zampini isidx = procs_candidates[rank]; 506157de7509SStefano Zampini } else { 506257de7509SStefano Zampini isidx = rank; 506357de7509SStefano Zampini } 506457de7509SStefano Zampini } else { 506557de7509SStefano Zampini issize = 0; 506657de7509SStefano Zampini isidx = -1; 506757de7509SStefano Zampini } 506857de7509SStefano Zampini *n_subdomains = active_procs; 506957de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 5070daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 507157de7509SStefano Zampini PetscFunctionReturn(0); 507257de7509SStefano Zampini } 5073c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 5074c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 507527b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 5076e7931f94SStefano Zampini 5077e7931f94SStefano Zampini /* Get info on mapping */ 50783bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 50793bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5080e7931f94SStefano Zampini 5081e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 5082785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 5083e7931f94SStefano Zampini xadj[0] = 0; 5084e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 5085785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 5086785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 508727b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 508827b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 508927b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 509027b6a85dSStefano Zampini count[shared[i][j]] += 1; 5091e7931f94SStefano Zampini 509227b6a85dSStefano Zampini xadj_count = 0; 50932b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 509427b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 509527b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 5096d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 5097d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 5098d023bfaeSStefano Zampini xadj_count++; 509927b6a85dSStefano Zampini break; 510027b6a85dSStefano Zampini } 5101e7931f94SStefano Zampini } 5102e7931f94SStefano Zampini } 5103d023bfaeSStefano Zampini xadj[1] = xadj_count; 510427b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 51053bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5106e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 5107e7931f94SStefano Zampini 51083837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 5109e7931f94SStefano Zampini 511027b6a85dSStefano Zampini /* Restrict work on active processes only */ 511127b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 511227b6a85dSStefano Zampini if (void_procs) { 511327b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 511427b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 511527b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 511627b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 511727b6a85dSStefano Zampini } else { 511827b6a85dSStefano Zampini psubcomm = NULL; 511927b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 512027b6a85dSStefano Zampini } 512127b6a85dSStefano Zampini 512227b6a85dSStefano Zampini v_wgt = NULL; 512327b6a85dSStefano Zampini if (!color) { 5124e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 5125e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 5126e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5127c8587f34SStefano Zampini } else { 512852e5ac9dSStefano Zampini Mat subdomain_adj; 512952e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 513052e5ac9dSStefano Zampini MatPartitioning partitioner; 513127b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 513252e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 513357de7509SStefano Zampini PetscMPIInt size; 5134b0c7d250SStefano Zampini PetscBool aggregate; 5135b0c7d250SStefano Zampini 513627b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 513727b6a85dSStefano Zampini if (void_procs) { 513827b6a85dSStefano Zampini PetscInt prank = rank; 5139785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 514027b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 5141e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 5142e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 5143c8587f34SStefano Zampini } 5144e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 514527b6a85dSStefano Zampini } else { 514627b6a85dSStefano Zampini oldranks = NULL; 514727b6a85dSStefano Zampini } 5148b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 514927b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 5150b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 5151b0c7d250SStefano Zampini PetscMPIInt nrank; 5152b0c7d250SStefano Zampini PetscScalar *vals; 5153b0c7d250SStefano Zampini 515427b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 5155b0c7d250SStefano Zampini lrows = 0; 5156b0c7d250SStefano Zampini if (nrank<redprocs) { 5157b0c7d250SStefano Zampini lrows = size/redprocs; 5158b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 5159b0c7d250SStefano Zampini } 516027b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 5161b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 5162b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5163b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5164b0c7d250SStefano Zampini row = nrank; 5165b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 5166b0c7d250SStefano Zampini cols = adjncy; 5167b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 5168b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 5169b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 5170b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5171b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 517252e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 517352e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 517452e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5175b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 517627b6a85dSStefano Zampini if (use_vwgt) { 517727b6a85dSStefano Zampini Vec v; 517827b6a85dSStefano Zampini const PetscScalar *array; 517927b6a85dSStefano Zampini PetscInt nl; 518027b6a85dSStefano Zampini 518127b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 518227b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 518327b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 518427b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 518527b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 518627b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 518727b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 518822db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 518927b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 519027b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 519127b6a85dSStefano Zampini } 5192b0c7d250SStefano Zampini } else { 519327b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 519427b6a85dSStefano Zampini if (use_vwgt) { 519527b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 519627b6a85dSStefano Zampini v_wgt[0] = local_size; 519727b6a85dSStefano Zampini } 5198b0c7d250SStefano Zampini } 519922b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 5200e7931f94SStefano Zampini 5201e7931f94SStefano Zampini /* Partition */ 520227b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 5203e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 520427b6a85dSStefano Zampini if (v_wgt) { 5205e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 5206c8587f34SStefano Zampini } 520757de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 520857de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 5209e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 5210e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 521122b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 5212e7931f94SStefano Zampini 521352e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 521452e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 521552e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 521652e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 521757de7509SStefano Zampini if (!aggregate) { 521857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 521927b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 522027b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 522127b6a85dSStefano Zampini #endif 522257de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 522327b6a85dSStefano Zampini } else if (oldranks) { 5224b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 522527b6a85dSStefano Zampini } else { 522627b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 522757de7509SStefano Zampini } 522828143c3dSStefano Zampini } else { 5229b0c7d250SStefano Zampini PetscInt idxs[1]; 5230b0c7d250SStefano Zampini PetscMPIInt tag; 5231b0c7d250SStefano Zampini MPI_Request *reqs; 5232b0c7d250SStefano Zampini 5233b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 5234b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 5235b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 523627b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 523728143c3dSStefano Zampini } 523827b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 5239b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5240b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 524157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 524227b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 524327b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 524427b6a85dSStefano Zampini #endif 524557de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 524627b6a85dSStefano Zampini } else if (oldranks) { 5247b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 524827b6a85dSStefano Zampini } else { 524927b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 5250e7931f94SStefano Zampini } 525157de7509SStefano Zampini } 525252e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5253e7931f94SStefano Zampini /* clean up */ 5254e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 525552e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 5256e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 5257e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 5258e7931f94SStefano Zampini } 525927b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 526057de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 5261e7931f94SStefano Zampini 5262e7931f94SStefano Zampini /* assemble parallel IS for sends */ 5263e7931f94SStefano Zampini i = 1; 526427b6a85dSStefano Zampini if (!color) i=0; 526557de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 5266e7931f94SStefano Zampini PetscFunctionReturn(0); 5267e7931f94SStefano Zampini } 5268e7931f94SStefano Zampini 5269e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 5270e7931f94SStefano Zampini 5271e7931f94SStefano Zampini #undef __FUNCT__ 5272e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 52731ae86dd6SStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, PetscBool reuse, Mat *mat_n, PetscInt nis, IS isarray[], PetscInt nvecs, Vec nnsp_vec[]) 5274e7931f94SStefano Zampini { 527570cf5478SStefano Zampini Mat local_mat; 5276e7931f94SStefano Zampini IS is_sends_internal; 52779d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 52781ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 52799d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 5280e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 5281e7931f94SStefano Zampini PetscInt* l2gmap_indices; 5282e7931f94SStefano Zampini const PetscInt* is_indices; 5283e7931f94SStefano Zampini MatType new_local_type; 5284e7931f94SStefano Zampini /* buffers */ 5285e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 528628143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 52879d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 5288e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 52891ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 5290e7931f94SStefano Zampini /* MPI */ 529128143c3dSStefano Zampini MPI_Comm comm,comm_n; 529228143c3dSStefano Zampini PetscSubcomm subcomm; 5293e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 529428143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 529528143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 52961ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 52971ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 52981ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 5299e7931f94SStefano Zampini PetscErrorCode ierr; 5300e7931f94SStefano Zampini 5301e7931f94SStefano Zampini PetscFunctionBegin; 530257de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5303e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 530428143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 530557de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 530657de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 530757de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 530857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 530957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 53101ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 53111ae86dd6SStefano Zampini if (nvecs) { 53121ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 53131ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 53141ae86dd6SStefano Zampini } 531557de7509SStefano Zampini /* further checks */ 5316e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5317e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 5318e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 5319e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 5320e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 532157de7509SStefano Zampini if (reuse && *mat_n) { 532270cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 532357de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 532470cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 532528143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 532670cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 532770cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 532870cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 532970cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 533070cf5478SStefano Zampini } 5331e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 5332e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 533357de7509SStefano Zampini 5334e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 5335e7931f94SStefano Zampini if (!is_sends) { 533628143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 533757de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 5338c8587f34SStefano Zampini } else { 5339e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 5340e7931f94SStefano Zampini is_sends_internal = is_sends; 5341c8587f34SStefano Zampini } 5342e7931f94SStefano Zampini 5343e7931f94SStefano Zampini /* get comm */ 5344a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 5345e7931f94SStefano Zampini 5346e7931f94SStefano Zampini /* compute number of sends */ 5347e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 5348e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 5349e7931f94SStefano Zampini 5350e7931f94SStefano Zampini /* compute number of receives */ 5351e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 5352785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 5353e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 5354e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5355e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 5356e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 5357e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 5358e7931f94SStefano Zampini 535928143c3dSStefano Zampini /* restrict comm if requested */ 536028143c3dSStefano Zampini subcomm = 0; 536128143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 536228143c3dSStefano Zampini if (restrict_comm) { 5363779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 5364779c1cceSStefano Zampini 536528143c3dSStefano Zampini color = 0; 536653a05cb3SStefano Zampini if (restrict_full) { 536753a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 536853a05cb3SStefano Zampini } else { 536953a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 537053a05cb3SStefano Zampini } 5371b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 537228143c3dSStefano Zampini subcommsize = commsize - subcommsize; 537328143c3dSStefano Zampini /* check if reuse has been requested */ 537457de7509SStefano Zampini if (reuse) { 537528143c3dSStefano Zampini if (*mat_n) { 537628143c3dSStefano Zampini PetscMPIInt subcommsize2; 537728143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 537828143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 537928143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 538028143c3dSStefano Zampini } else { 538128143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 538228143c3dSStefano Zampini } 538328143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 5384779c1cceSStefano Zampini PetscMPIInt rank; 5385779c1cceSStefano Zampini 5386779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 538728143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 538828143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 538928143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 5390306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 539128143c3dSStefano Zampini } 539228143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 539328143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 539428143c3dSStefano Zampini } else { 539528143c3dSStefano Zampini comm_n = comm; 539628143c3dSStefano Zampini } 539728143c3dSStefano Zampini 5398e7931f94SStefano Zampini /* prepare send/receive buffers */ 5399785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 5400e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 5401785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 5402e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 540328143c3dSStefano Zampini if (nis) { 5404854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 540528143c3dSStefano Zampini } 5406e7931f94SStefano Zampini 540728143c3dSStefano Zampini /* Get data from local matrices */ 54086c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 5409e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 5410e7931f94SStefano Zampini /* 5411e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 5412e7931f94SStefano Zampini send_buffer_idxs should contain: 5413e7931f94SStefano Zampini - MatType_PRIVATE type 5414e7931f94SStefano Zampini - PetscInt size_of_l2gmap 5415e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 5416e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 5417e7931f94SStefano Zampini */ 54186c4ed002SBarry Smith else { 5419e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 54203bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 5421854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 5422e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 5423e7931f94SStefano Zampini send_buffer_idxs[1] = i; 54243bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5425e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 54263bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5427e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 5428e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5429e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 5430e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 5431c8587f34SStefano Zampini } 5432c8587f34SStefano Zampini } 5433e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 543428143c3dSStefano Zampini /* additional is (if any) */ 543528143c3dSStefano Zampini if (nis) { 543628143c3dSStefano Zampini PetscMPIInt psum; 543728143c3dSStefano Zampini PetscInt j; 543828143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 543928143c3dSStefano Zampini PetscInt plen; 544028143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 544128143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 544228143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 544328143c3dSStefano Zampini } 5444854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 544528143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 544628143c3dSStefano Zampini PetscInt plen; 544728143c3dSStefano Zampini const PetscInt *is_array_idxs; 544828143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 544928143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 545028143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 545128143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 545228143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 545328143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 545428143c3dSStefano Zampini } 545528143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 545628143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 545728143c3dSStefano Zampini } 545828143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 545928143c3dSStefano Zampini } 546028143c3dSStefano Zampini 5461e7931f94SStefano Zampini buf_size_idxs = 0; 5462e7931f94SStefano Zampini buf_size_vals = 0; 546328143c3dSStefano Zampini buf_size_idxs_is = 0; 54641ae86dd6SStefano Zampini buf_size_vecs = 0; 5465e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5466e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 5467e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 546828143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 54691ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 5470e7931f94SStefano Zampini } 5471785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 5472785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 547395ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 54741ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 5475e7931f94SStefano Zampini 5476e7931f94SStefano Zampini /* get new tags for clean communications */ 5477e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 5478e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 547928143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 54801ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 5481e7931f94SStefano Zampini 5482e7931f94SStefano Zampini /* allocate for requests */ 5483785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 5484785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 548595ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 54861ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 5487785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 5488785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 548995ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 54901ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 5491e7931f94SStefano Zampini 5492e7931f94SStefano Zampini /* communications */ 5493e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5494e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 549528143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 54961ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 5497e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5498e7931f94SStefano Zampini source_dest = onodes[i]; 5499e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 5500e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 5501e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5502e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 550328143c3dSStefano Zampini if (nis) { 550457de7509SStefano Zampini source_dest = onodes_is[i]; 550528143c3dSStefano 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); 550628143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 550728143c3dSStefano Zampini } 55081ae86dd6SStefano Zampini if (nvecs) { 55091ae86dd6SStefano Zampini source_dest = onodes[i]; 55101ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 55111ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 55121ae86dd6SStefano Zampini } 5513e7931f94SStefano Zampini } 5514e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5515e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 5516e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 5517e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 551828143c3dSStefano Zampini if (nis) { 551928143c3dSStefano 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); 552028143c3dSStefano Zampini } 55211ae86dd6SStefano Zampini if (nvecs) { 55221ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 55231ae86dd6SStefano Zampini ierr = MPI_Isend(send_buffer_vecs,ilengths_idxs[source_dest]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&send_req_vecs[i]);CHKERRQ(ierr); 55241ae86dd6SStefano Zampini } 5525e7931f94SStefano Zampini } 5526e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5527e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 5528e7931f94SStefano Zampini 5529e7931f94SStefano Zampini /* assemble new l2g map */ 5530e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5531e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 55329d30be91SStefano Zampini new_local_rows = 0; 5533e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 55349d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5535e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5536e7931f94SStefano Zampini } 55379d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 5538e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 55399d30be91SStefano Zampini new_local_rows = 0; 5540e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 55419d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 55429d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5543e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5544e7931f94SStefano Zampini } 55459d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 55469d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 5547e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 5548e7931f94SStefano Zampini 5549e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 5550e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 5551e7931f94SStefano 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) */ 5552e7931f94SStefano Zampini if (n_recvs) { 555328143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 5554e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5555e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5556e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 5557e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 5558e7931f94SStefano Zampini break; 5559e7931f94SStefano Zampini } 5560e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5561e7931f94SStefano Zampini } 5562e7931f94SStefano Zampini switch (new_local_type_private) { 556328143c3dSStefano Zampini case MATDENSE_PRIVATE: 556428143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 5565e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5566e7931f94SStefano Zampini bs = 1; 556728143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 556828143c3dSStefano Zampini new_local_type = MATSEQDENSE; 556928143c3dSStefano Zampini bs = 1; 557028143c3dSStefano Zampini } 5571e7931f94SStefano Zampini break; 5572e7931f94SStefano Zampini case MATAIJ_PRIVATE: 5573e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5574e7931f94SStefano Zampini bs = 1; 5575e7931f94SStefano Zampini break; 5576e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 5577e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 5578e7931f94SStefano Zampini break; 5579e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 5580e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 5581e7931f94SStefano Zampini break; 5582e7931f94SStefano Zampini default: 55839d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 5584e7931f94SStefano Zampini break; 5585e7931f94SStefano Zampini } 558628143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 558728143c3dSStefano Zampini new_local_type = MATSEQDENSE; 558828143c3dSStefano Zampini bs = 1; 5589e7931f94SStefano Zampini } 5590e7931f94SStefano Zampini 559170cf5478SStefano Zampini /* create MATIS object if needed */ 559257de7509SStefano Zampini if (!reuse) { 5593e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 5594e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 559570cf5478SStefano Zampini } else { 559670cf5478SStefano Zampini /* it also destroys the local matrices */ 559757de7509SStefano Zampini if (*mat_n) { 559870cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 559957de7509SStefano Zampini } else { /* this is a fake object */ 560057de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 560157de7509SStefano Zampini } 560270cf5478SStefano Zampini } 560370cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 5604e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 56059d30be91SStefano Zampini 56069d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 56079d30be91SStefano Zampini 56089d30be91SStefano Zampini /* Global to local map of received indices */ 56099d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 56109d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 56119d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 56129d30be91SStefano Zampini 56139d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 56149d30be91SStefano Zampini buf_size_idxs = 0; 56159d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 56169d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 56179d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 56189d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 56199d30be91SStefano Zampini } 56209d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 56219d30be91SStefano Zampini 56229d30be91SStefano Zampini /* set preallocation */ 56239d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 56249d30be91SStefano Zampini if (!newisdense) { 56259d30be91SStefano Zampini PetscInt *new_local_nnz=0; 56269d30be91SStefano Zampini 56279d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 56289d30be91SStefano Zampini if (n_recvs) { 56299d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 56309d30be91SStefano Zampini } 56319d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 56329d30be91SStefano Zampini PetscInt j; 56339d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 56349d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 56359d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 56369d30be91SStefano Zampini } 56379d30be91SStefano Zampini } else { 56389d30be91SStefano Zampini /* TODO */ 56399d30be91SStefano Zampini } 56409d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 56419d30be91SStefano Zampini } 56429d30be91SStefano Zampini if (new_local_nnz) { 56439d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 56449d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 56459d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 56469d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 56479d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 56489d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 56499d30be91SStefano Zampini } else { 56509d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 56519d30be91SStefano Zampini } 56529d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 56539d30be91SStefano Zampini } else { 56549d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 56559d30be91SStefano Zampini } 5656e7931f94SStefano Zampini 5657e7931f94SStefano Zampini /* set values */ 5658e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 56599d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5660e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5661e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5662e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 56639d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5664e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5665e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5666e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 566728143c3dSStefano Zampini } else { 566828143c3dSStefano Zampini /* TODO */ 5669e7931f94SStefano Zampini } 5670e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5671e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5672e7931f94SStefano Zampini } 5673e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5674e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 567570cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 567670cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 56779d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 5678e7931f94SStefano Zampini 5679dfd14d43SStefano Zampini #if 0 568028143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5681e7931f94SStefano Zampini Vec lvec,rvec; 5682e7931f94SStefano Zampini PetscReal infty_error; 5683e7931f94SStefano Zampini 56842a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5685e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5686e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5687e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 568870cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5689e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5690e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5691e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5692e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5693e7931f94SStefano Zampini } 569428143c3dSStefano Zampini #endif 5695e7931f94SStefano Zampini 569628143c3dSStefano Zampini /* assemble new additional is (if any) */ 569728143c3dSStefano Zampini if (nis) { 569828143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 569928143c3dSStefano Zampini 570028143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5701854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 570228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 570328143c3dSStefano Zampini psum = 0; 570428143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 570528143c3dSStefano Zampini for (j=0;j<nis;j++) { 570628143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 570728143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 570828143c3dSStefano Zampini psum += plen; 570928143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 571028143c3dSStefano Zampini } 571128143c3dSStefano Zampini } 5712854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5713854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 571428143c3dSStefano Zampini for (i=1;i<nis;i++) { 571528143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 571628143c3dSStefano Zampini } 571728143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 571828143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 571928143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 572028143c3dSStefano Zampini for (j=0;j<nis;j++) { 572128143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 572228143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 572328143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 572428143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 572528143c3dSStefano Zampini } 572628143c3dSStefano Zampini } 572728143c3dSStefano Zampini for (i=0;i<nis;i++) { 572828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 572928143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 573028143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 573128143c3dSStefano Zampini } 573228143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 573328143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 573428143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 573528143c3dSStefano Zampini } 5736e7931f94SStefano Zampini /* free workspace */ 573728143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5738e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5739e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5740e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5741e7931f94SStefano Zampini if (isdense) { 5742e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5743e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5744e7931f94SStefano Zampini } else { 5745e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5746e7931f94SStefano Zampini } 574728143c3dSStefano Zampini if (nis) { 574828143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 574928143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 575028143c3dSStefano Zampini } 57511ae86dd6SStefano Zampini 57521ae86dd6SStefano Zampini if (nvecs) { 57531ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 57541ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 57551ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 57561ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 57571ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 57581ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 57591ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 57601ae86dd6SStefano Zampini /* set values */ 57611ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 57621ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 57631ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 57641ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 57651ae86dd6SStefano Zampini PetscInt j; 57661ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 57671ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 57681ae86dd6SStefano Zampini } 57691ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 57701ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 57711ae86dd6SStefano Zampini } 57721ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 57731ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 57741ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 57751ae86dd6SStefano Zampini } 57761ae86dd6SStefano Zampini 57771ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 57781ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5779e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5780e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 57811ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 578228143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5783e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5784e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 57851ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 578628143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5787e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5788e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5789e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5790e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5791e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 579228143c3dSStefano Zampini if (nis) { 579328143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 579428143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 579528143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 579628143c3dSStefano Zampini } 579728143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 579828143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 579928143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 580028143c3dSStefano Zampini for (i=0;i<nis;i++) { 580128143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 580228143c3dSStefano Zampini } 58031ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 58041ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 58051ae86dd6SStefano Zampini } 580653a05cb3SStefano Zampini *mat_n = NULL; 580728143c3dSStefano Zampini } 5808e7931f94SStefano Zampini PetscFunctionReturn(0); 5809e7931f94SStefano Zampini } 5810a57a6d2fSStefano Zampini 581112edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5812af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 581312edc857SStefano Zampini 5814c8587f34SStefano Zampini #undef __FUNCT__ 5815c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5816c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5817c8587f34SStefano Zampini { 5818c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5819c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 582020a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 58211ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 58229881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 582320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 58246e683305SStefano Zampini IS coarse_is,*isarray; 58256e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 582630368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5827f9eb5b7dSStefano Zampini PC pc_temp; 5828c8587f34SStefano Zampini PCType coarse_pc_type; 5829c8587f34SStefano Zampini KSPType coarse_ksp_type; 5830f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 58314f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 58326e683305SStefano Zampini Mat t_coarse_mat_is; 583357de7509SStefano Zampini PetscInt ncoarse; 583468457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 583522bc73bbSStefano Zampini PetscScalar *array; 583657de7509SStefano Zampini MatReuse coarse_mat_reuse; 583757de7509SStefano Zampini PetscBool restr, full_restr, have_void; 58389881197aSStefano Zampini PetscErrorCode ierr; 5839fdc09c96SStefano Zampini 5840c8587f34SStefano Zampini PetscFunctionBegin; 5841c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 584268457ee5SStefano 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 */ 5843fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 58445a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5845fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5846f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5847f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5848f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5849fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 585051bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 585151bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5852dc4bcba2SStefano Zampini PC pc; 5853dc4bcba2SStefano Zampini PetscBool isbddc; 5854dc4bcba2SStefano Zampini 5855dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5856dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5857dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5858dc4bcba2SStefano Zampini if (isbddc) { 585963c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 586063c961adSStefano Zampini } else { 5861727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 586263c961adSStefano Zampini } 5863fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5864fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5865fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5866f4ddd8eeSStefano Zampini } 5867fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5868fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5869f4ddd8eeSStefano Zampini } 587070cf5478SStefano Zampini /* reset any subassembling information */ 587157de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 587270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 587357de7509SStefano Zampini } 58746e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5875fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5876f4ddd8eeSStefano Zampini } 587757de7509SStefano Zampini /* assemble coarse matrix */ 587857de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 587957de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 588057de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 588157de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 588218a45a71SStefano Zampini } else { 588357de7509SStefano Zampini coarse_mat = NULL; 588457de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 58856e683305SStefano Zampini } 5886e7931f94SStefano Zampini 5887abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5888abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5889abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5890abbbba34SStefano Zampini 5891abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 589222bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 589322bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 589422bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 589522bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5896e176bc59SStefano 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); 58976e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 58986e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 58996e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5900abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5901abbbba34SStefano Zampini 590257de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 590357de7509SStefano Zampini im_active = !!(pcis->n); 590457de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 590557de7509SStefano Zampini 590657de7509SStefano Zampini /* determine number of process partecipating to coarse solver and compute subassembling pattern */ 590757de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 590857de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 590957de7509SStefano Zampini coarse_mat_is = NULL; 591057de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 591157de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 591257de7509SStefano Zampini full_restr = PETSC_TRUE; 59131ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 591457de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 591557de7509SStefano Zampini if (multilevel_requested) { 591657de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 591757de7509SStefano Zampini restr = PETSC_FALSE; 591857de7509SStefano Zampini full_restr = PETSC_FALSE; 591957de7509SStefano Zampini } else { 592057de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 592157de7509SStefano Zampini restr = PETSC_TRUE; 592257de7509SStefano Zampini full_restr = PETSC_TRUE; 592357de7509SStefano Zampini } 59244b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 592557de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 592657de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 5927a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 592857de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 5929a198735bSStefano Zampini } else { 5930a198735bSStefano Zampini PetscMPIInt size,rank; 5931a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 5932a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 5933a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 5934a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 5935a198735bSStefano Zampini } 593657de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 593757de7509SStefano Zampini PetscInt psum; 593857de7509SStefano Zampini PetscMPIInt size; 593957de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 594057de7509SStefano Zampini else psum = 0; 594157de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 594257de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 594357de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 594457de7509SStefano Zampini } 594557de7509SStefano Zampini /* determine if we can go multilevel */ 594657de7509SStefano Zampini if (multilevel_requested) { 594757de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 594857de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 594957de7509SStefano Zampini } 595057de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 595157de7509SStefano Zampini 5952e4d548c7SStefano Zampini /* dump subassembling pattern */ 5953e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 5954e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 5955e4d548c7SStefano Zampini } 5956e4d548c7SStefano Zampini 59576e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 595827b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 59596e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 59606e683305SStefano Zampini const PetscInt *idxs; 59616e683305SStefano Zampini ISLocalToGlobalMapping tmap; 59626e683305SStefano Zampini 59636e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 59640be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 59656e683305SStefano Zampini /* allocate space for temporary storage */ 5966854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5967854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 59686e683305SStefano Zampini /* allocate for IS array */ 59696e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 59706e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 597127b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 597230368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5973854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 59746e683305SStefano Zampini /* dofs splitting */ 59756e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 59766e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 59776e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 59786e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 59796e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 59806e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 59816e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 598230368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 59836e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 59846e683305SStefano Zampini } 59856e683305SStefano Zampini /* neumann boundaries */ 59866e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 59876e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 59886e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 59896e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 59906e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 59916e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 59926e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 599330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 59946e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 59956e683305SStefano Zampini } 59966e683305SStefano Zampini /* free memory */ 59976e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 59986e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 59996e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 60006e683305SStefano Zampini } else { 60016e683305SStefano Zampini nis = 0; 60026e683305SStefano Zampini nisdofs = 0; 60036e683305SStefano Zampini nisneu = 0; 600430368db7SStefano Zampini nisvert = 0; 60056e683305SStefano Zampini isarray = NULL; 60066e683305SStefano Zampini } 60076e683305SStefano Zampini /* destroy no longer needed map */ 60086e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 60096e683305SStefano Zampini 601057de7509SStefano Zampini /* subassemble */ 601157de7509SStefano Zampini if (multilevel_allowed) { 60121ae86dd6SStefano Zampini Vec vp[1]; 60131ae86dd6SStefano Zampini PetscInt nvecs = 0; 601457de7509SStefano Zampini PetscBool reuse,reuser; 60151ae86dd6SStefano Zampini 601657de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 601757de7509SStefano Zampini else reuse = PETSC_FALSE; 601857de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 60191ae86dd6SStefano Zampini vp[0] = NULL; 60201ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 60211ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 60221ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 60231ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 60241ae86dd6SStefano Zampini nvecs = 1; 60251ae86dd6SStefano Zampini 60261ae86dd6SStefano Zampini if (pcbddc->divudotp) { 6027a198735bSStefano Zampini Mat B,loc_divudotp; 60281ae86dd6SStefano Zampini Vec v,p; 60291ae86dd6SStefano Zampini IS dummy; 60301ae86dd6SStefano Zampini PetscInt np; 60311ae86dd6SStefano Zampini 6032a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 6033a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 60341ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 6035a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 60361ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 60371ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 60381ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 60391ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 60401ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 60411ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 60421ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 60431ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 60441ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 60451ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 60461ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 60471ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 604874e2c79eSStefano Zampini } 60491ae86dd6SStefano Zampini } 60501ae86dd6SStefano Zampini if (reuser) { 60511ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 605274e2c79eSStefano Zampini } else { 60531ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,nvecs,vp);CHKERRQ(ierr); 60541ae86dd6SStefano Zampini } 60551ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 60561ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 60571ae86dd6SStefano Zampini PetscInt nl; 60581ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 60591ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 60601ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 60611ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 60621ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 60631ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 60641ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 60651ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 6066a198735bSStefano Zampini } else { 6067a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 60681ae86dd6SStefano Zampini } 60691ae86dd6SStefano Zampini } else { 60701ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,0,NULL);CHKERRQ(ierr); 60716e683305SStefano Zampini } 607257de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 607357de7509SStefano Zampini PetscMPIInt size; 607457de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 607557de7509SStefano Zampini if (!multilevel_allowed) { 607657de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 60776e683305SStefano Zampini } else { 607857de7509SStefano Zampini Mat A; 6079779c1cceSStefano Zampini 608057de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 608157de7509SStefano Zampini if (coarse_mat_is) { 608257de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 608357de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 608457de7509SStefano Zampini coarse_mat = coarse_mat_is; 608557de7509SStefano Zampini } 608657de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 608757de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 608857de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 6089779c1cceSStefano Zampini } 6090779c1cceSStefano Zampini } 609157de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 609257de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 60936e683305SStefano Zampini 60946e683305SStefano Zampini /* create local to global scatters for coarse problem */ 609568457ee5SStefano Zampini if (compute_vecs) { 60966e683305SStefano Zampini PetscInt lrows; 60976e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 609857de7509SStefano Zampini if (coarse_mat) { 609957de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 61006e683305SStefano Zampini } else { 61016e683305SStefano Zampini lrows = 0; 61026e683305SStefano Zampini } 61036e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 61046e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 61056e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 61066e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 61076e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 61086e683305SStefano Zampini } 61096e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 6110c8587f34SStefano Zampini 6111f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 6112f9eb5b7dSStefano Zampini if (multilevel_allowed) { 6113f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 6114f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 6115f9eb5b7dSStefano Zampini } else { 6116f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 6117f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 6118c8587f34SStefano Zampini } 6119c8587f34SStefano Zampini 61206e683305SStefano Zampini /* print some info if requested */ 61216e683305SStefano Zampini if (pcbddc->dbg_flag) { 61226e683305SStefano Zampini if (!multilevel_allowed) { 61236e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 61246e683305SStefano Zampini if (multilevel_requested) { 61256e683305SStefano 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); 61266e683305SStefano Zampini } else if (pcbddc->max_levels) { 61276e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 61286e683305SStefano Zampini } 61296e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 61306e683305SStefano Zampini } 61316e683305SStefano Zampini } 61326e683305SStefano Zampini 6133f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 613457de7509SStefano Zampini if (coarse_mat) { 61356a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 61366e683305SStefano Zampini if (pcbddc->dbg_flag) { 613757de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 61386e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 61396e683305SStefano Zampini } 6140f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 6141312be037SStefano Zampini char prefix[256],str_level[16]; 6142e604994aSStefano Zampini size_t len; 614357de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 6144422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 6145c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 6146f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 614757de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6148c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 61496e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 6150c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 6151c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6152e604994aSStefano Zampini /* prefix */ 6153e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 6154e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 6155e604994aSStefano Zampini if (!pcbddc->current_level) { 6156e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 6157e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 6158c8587f34SStefano Zampini } else { 6159e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 6160312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 6161312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 616234d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 6163312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 6164e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 6165e604994aSStefano Zampini } 6166e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 61673e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 61683e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 61693e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 61703e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 6171f9eb5b7dSStefano Zampini /* allow user customization */ 6172f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 61733e3c6dadSStefano Zampini } 61743e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 617551bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 61763e3c6dadSStefano Zampini if (nisdofs) { 61773e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 61783e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 61793e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 61803e3c6dadSStefano Zampini } 61813e3c6dadSStefano Zampini } 61823e3c6dadSStefano Zampini if (nisneu) { 61833e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 61843e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 6185312be037SStefano Zampini } 618630368db7SStefano Zampini if (nisvert) { 618730368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 618830368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 618930368db7SStefano Zampini } 6190f9eb5b7dSStefano Zampini 6191f9eb5b7dSStefano Zampini /* get some info after set from options */ 6192f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 6193f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 61944f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 61956e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 6196f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6197f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 6198f9eb5b7dSStefano Zampini } 619939f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 62004f3a063dSStefano Zampini if (isredundant) { 62014f3a063dSStefano Zampini KSP inner_ksp; 62024f3a063dSStefano Zampini PC inner_pc; 62034f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 62044f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 62054f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 62064f3a063dSStefano Zampini } 6207f9eb5b7dSStefano Zampini 620857de7509SStefano Zampini /* parameters which miss an API */ 620957de7509SStefano Zampini if (isbddc) { 6210720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 6211720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 621257de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 621327b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 621427b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 6215a198735bSStefano Zampini Mat coarsedivudotp_is; 6216a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 6217a198735bSStefano Zampini IS row,col; 6218a198735bSStefano Zampini const PetscInt *gidxs; 6219a198735bSStefano Zampini PetscInt n,st,M,N; 6220a198735bSStefano Zampini 6221a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 6222a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 6223a198735bSStefano Zampini st = st-n; 6224a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 6225a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 6226a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 6227a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6228a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 6229a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6230a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 6231a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 6232a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 6233a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 6234a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 6235a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 6236a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 6237a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 6238a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 6239a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 6240a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6241a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6242a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 6243a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 6244a198735bSStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,NULL);CHKERRQ(ierr); 6245a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 6246720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 624759e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 6248720d30f9SStefano Zampini } 6249d4d8cf7bSStefano Zampini } 62509881197aSStefano Zampini 62513301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 62525a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 62533301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 62543301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 62553301b35fSStefano Zampini } 62563301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 62573301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 62583301b35fSStefano Zampini } 62593301b35fSStefano Zampini if (pc->pmat->spd_set) { 62603301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 62613301b35fSStefano Zampini } 626227b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 626327b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 626427b6a85dSStefano Zampini } 62656e683305SStefano Zampini /* set operators */ 62665f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 62676e683305SStefano Zampini if (pcbddc->dbg_flag) { 62686e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 62696e683305SStefano Zampini } 62706e683305SStefano Zampini } 62716e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 6272b1ecc7b1SStefano Zampini #if 0 6273b9b85e73SStefano Zampini { 6274b9b85e73SStefano Zampini PetscViewer viewer; 6275b9b85e73SStefano Zampini char filename[256]; 6276b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 6277b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 62786a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6279b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 6280f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 6281b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 6282b9b85e73SStefano Zampini } 6283b9b85e73SStefano Zampini #endif 6284f9eb5b7dSStefano Zampini 628598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 628698a51de6SStefano Zampini Vec crhs,csol; 628704708bb6SStefano Zampini 6288f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 6289f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 6290f347579bSStefano Zampini if (!csol) { 62912a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 6292f9eb5b7dSStefano Zampini } 6293f347579bSStefano Zampini if (!crhs) { 62942a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 6295f347579bSStefano Zampini } 6296b0f5fe93SStefano Zampini } 62971ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 6298b0f5fe93SStefano Zampini 6299b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 6300b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 6301b0f5fe93SStefano Zampini 6302b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 63034f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 63044f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 63054f1b2e48SStefano Zampini } 6306b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 6307b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 6308b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6309b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6310b0f5fe93SStefano Zampini if (coarse_mat) { 6311b0f5fe93SStefano Zampini Vec nullv; 6312b0f5fe93SStefano Zampini PetscScalar *array,*array2; 6313b0f5fe93SStefano Zampini PetscInt nl; 6314b0f5fe93SStefano Zampini 6315b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 6316b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 6317b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6318b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 6319b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 6320b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 6321b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6322b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 6323b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 6324b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 6325b0f5fe93SStefano Zampini } 6326b0f5fe93SStefano Zampini } 6327b0f5fe93SStefano Zampini 6328b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 6329b0f5fe93SStefano Zampini PetscBool ispreonly; 6330b0f5fe93SStefano Zampini 6331b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6332b0f5fe93SStefano Zampini PetscBool isnull; 6333b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 6334bef83e63SStefano Zampini if (isnull) { 6335b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 6336b0f5fe93SStefano Zampini } 6337bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 6338b0f5fe93SStefano Zampini } 6339b0f5fe93SStefano Zampini /* setup coarse ksp */ 6340b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 6341cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 6342cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 63436e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 6344c8587f34SStefano Zampini KSP check_ksp; 63452b510759SStefano Zampini KSPType check_ksp_type; 6346c8587f34SStefano Zampini PC check_pc; 63476e683305SStefano Zampini Vec check_vec,coarse_vec; 63486a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 63492b510759SStefano Zampini PetscInt its; 63506e683305SStefano Zampini PetscBool compute_eigs; 63516e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 63526e683305SStefano Zampini PetscInt neigs; 63538e185a42SStefano Zampini const char *prefix; 6354c8587f34SStefano Zampini 63552b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 63566e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 6357422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 635823ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6359f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 6360e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 6361e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 6362e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 63632b510759SStefano Zampini if (ispreonly) { 63642b510759SStefano Zampini check_ksp_type = KSPPREONLY; 63656e683305SStefano Zampini compute_eigs = PETSC_FALSE; 63662b510759SStefano Zampini } else { 6367cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 63686e683305SStefano Zampini compute_eigs = PETSC_TRUE; 6369c8587f34SStefano Zampini } 6370c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 63716e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 63726e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 63736e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 6374a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 6375a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 6376a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 6377a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 6378c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 6379c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 6380c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 6381c8587f34SStefano Zampini /* create random vec */ 63822701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 6383c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 63846e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 6385c8587f34SStefano Zampini /* solve coarse problem */ 63866e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 6387cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 63886e683305SStefano Zampini if (compute_eigs) { 6389854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 6390854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 63916e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 63921ae86dd6SStefano Zampini if (neigs) { 63936e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 63946e683305SStefano Zampini lambda_min = eigs_r[0]; 63956e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 63962701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 63972701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 6398cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 6399cbcc2c2aSStefano Zampini } 6400c8587f34SStefano Zampini } 6401c8587f34SStefano Zampini } 64021ae86dd6SStefano Zampini } 6403cbcc2c2aSStefano Zampini 6404c8587f34SStefano Zampini /* check coarse problem residual error */ 64056e683305SStefano Zampini if (pcbddc->dbg_flag) { 64066e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 64076e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 64086e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 6409c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 64106e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 64116e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 6412779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 64136e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 64146e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 64156e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 64166e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 6417b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6418b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 6419b0f5fe93SStefano Zampini } 64206e683305SStefano Zampini if (compute_eigs) { 64216e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 6422deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 6423c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 64246e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 64256e683305SStefano 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); 64266e683305SStefano Zampini for (i=0;i<neigs;i++) { 64276e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 6428c8587f34SStefano Zampini } 64296e683305SStefano Zampini } 64306e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 64316e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 64326e683305SStefano Zampini } 6433e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 64342701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 6435c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 64366e683305SStefano Zampini if (compute_eigs) { 64376e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 64386e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 6439c8587f34SStefano Zampini } 64406e683305SStefano Zampini } 64416e683305SStefano Zampini } 6442bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 6443cbcc2c2aSStefano Zampini /* print additional info */ 6444cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 64456e683305SStefano Zampini /* waits until all processes reaches this point */ 64466e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 6447cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 6448cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6449cbcc2c2aSStefano Zampini } 6450cbcc2c2aSStefano Zampini 64512b510759SStefano Zampini /* free memory */ 6452fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 6453c8587f34SStefano Zampini PetscFunctionReturn(0); 6454c8587f34SStefano Zampini } 6455674ae819SStefano Zampini 6456f34684f1SStefano Zampini #undef __FUNCT__ 6457f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 6458f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 6459f34684f1SStefano Zampini { 6460f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6461f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 6462f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 6463dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 6464dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 646573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 6466dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 6467f34684f1SStefano Zampini PetscErrorCode ierr; 6468f34684f1SStefano Zampini 6469f34684f1SStefano Zampini PetscFunctionBegin; 6470f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 64716c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 6472dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 64733bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 6474dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6475dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 6476dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 6477dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 6478dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 6479dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 64806c4ed002SBarry Smith if (local_size != pcbddc->local_primal_size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %D != %D",local_size,pcbddc->local_primal_size); 6481dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 6482dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6483dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 6484dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6485dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6486f34684f1SStefano Zampini 6487f34684f1SStefano Zampini /* check numbering */ 6488f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 6489019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 6490dc456d91SStefano Zampini PetscInt i; 6491b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 6492f34684f1SStefano Zampini 6493f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6494f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 6495f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 64961575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6497019a44ceSStefano Zampini /* counter */ 6498019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6499019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6500019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6501019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6502019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6503019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6504f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 6505f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 6506727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6507f34684f1SStefano Zampini } 6508f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6509f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6510f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6511e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6512e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6513e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6514e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6515f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6516019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6517f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6518019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 65192c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 652075c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 6521b9b85e73SStefano Zampini set_error = PETSC_TRUE; 65222c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 65232c66d082SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d (gid %d) owned by %d processes instead of %d!\n",PetscGlobalRank,i,gi,owned,neigh);CHKERRQ(ierr); 6524f34684f1SStefano Zampini } 6525f34684f1SStefano Zampini } 6526019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6527b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 6528f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6529f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6530f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 6531f34684f1SStefano Zampini } 6532f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6533f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6534e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6535e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6536f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 6537f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 6538b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 6539ca8b9ea9SStefano Zampini PetscInt *gidxs; 6540ca8b9ea9SStefano Zampini 6541ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 65423bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 6543f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 6544f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6545f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6546f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 65474bc2dc4bSStefano 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); 6548f34684f1SStefano Zampini } 6549f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6550ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 6551f34684f1SStefano Zampini } 6552f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 65531575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6554302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 6555f34684f1SStefano Zampini } 65568bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 6557f34684f1SStefano Zampini /* get back data */ 6558f34684f1SStefano Zampini *coarse_size_n = coarse_size; 6559f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 6560674ae819SStefano Zampini PetscFunctionReturn(0); 6561674ae819SStefano Zampini } 6562674ae819SStefano Zampini 6563e456f2a8SStefano Zampini #undef __FUNCT__ 6564e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 6565a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 6566e456f2a8SStefano Zampini { 6567e456f2a8SStefano Zampini IS localis_t; 6568a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 6569e456f2a8SStefano Zampini PetscScalar *vals; 6570e456f2a8SStefano Zampini PetscErrorCode ierr; 6571e456f2a8SStefano Zampini 6572e456f2a8SStefano Zampini PetscFunctionBegin; 6573a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 6574e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 6575854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 6576e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 6577e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6578a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 6579a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 65801035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 6581a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 65821035eff8SStefano Zampini } 6583a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 6584e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6585e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6586a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 6587a7dc3881SStefano Zampini /* now compute set in local ordering */ 6588a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6589a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6590a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6591a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 6592a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6593ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6594e456f2a8SStefano Zampini lsize++; 6595e456f2a8SStefano Zampini } 6596e456f2a8SStefano Zampini } 6597854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 6598a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6599ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6600e456f2a8SStefano Zampini idxs[lsize++] = i; 6601e456f2a8SStefano Zampini } 6602e456f2a8SStefano Zampini } 6603a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6604a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 6605e456f2a8SStefano Zampini *localis = localis_t; 6606e456f2a8SStefano Zampini PetscFunctionReturn(0); 6607e456f2a8SStefano Zampini } 6608906d46d4SStefano Zampini 6609b96c3477SStefano Zampini #undef __FUNCT__ 6610b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 661108122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 6612b96c3477SStefano Zampini { 6613a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6614b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6615b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6616a64f4aa4SStefano Zampini Mat S_j; 6617b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6618b96c3477SStefano Zampini PetscBool free_used_adj; 6619b96c3477SStefano Zampini PetscErrorCode ierr; 6620b96c3477SStefano Zampini 6621b96c3477SStefano Zampini PetscFunctionBegin; 6622b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6623b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 662408122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6625b96c3477SStefano Zampini used_xadj = NULL; 6626b96c3477SStefano Zampini used_adjncy = NULL; 6627b96c3477SStefano Zampini } else { 662808122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 662908122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 663008122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 663108122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6632b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6633b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6634b96c3477SStefano Zampini } else { 66352fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6636b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6637b96c3477SStefano Zampini PetscInt nvtxs; 6638b96c3477SStefano Zampini 66392fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 66402fffb893SStefano Zampini if (flg_row) { 6641b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6642b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6643b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6644b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 66452fffb893SStefano Zampini } else { 66462fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 66472fffb893SStefano Zampini used_xadj = NULL; 66482fffb893SStefano Zampini used_adjncy = NULL; 66492fffb893SStefano Zampini } 66502fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6651b96c3477SStefano Zampini } 6652b96c3477SStefano Zampini } 6653d5574798SStefano Zampini 6654d5574798SStefano Zampini /* setup sub_schurs data */ 6655a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6656df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 6657df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 6658a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 665991af6908SStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,NULL,S_j,PETSC_FALSE,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,NULL,pcbddc->adaptive_selection,PETSC_FALSE,PETSC_FALSE,0,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 6660a64f4aa4SStefano Zampini } else { 66616816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 6662b7ab4a40SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE;; 6663a3df083aSStefano Zampini PetscInt benign_n; 666472b8c272SStefano Zampini Mat change = NULL; 66659d54b7f4SStefano Zampini Vec scaling = NULL; 666672b8c272SStefano Zampini IS change_primal = NULL; 6667a3df083aSStefano Zampini 66685feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 66695feab87aSStefano Zampini PetscInt n_vertices; 66705feab87aSStefano Zampini 66715feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 66722034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 66735feab87aSStefano Zampini } 667404708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 667504708bb6SStefano Zampini if (!isseqaij) { 667604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 667704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 667804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 667904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 668004708bb6SStefano Zampini } else { 6681511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 668204708bb6SStefano Zampini } 668304708bb6SStefano Zampini } 6684a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6685a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6686ca92afb2SStefano Zampini } else { 6687a3df083aSStefano Zampini benign_n = 0; 6688ca92afb2SStefano Zampini } 6689b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 6690b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 6691b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 669272b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 669322db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 6694b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 669522db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 6696b7ab4a40SStefano Zampini } 6697b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 6698b7ab4a40SStefano Zampini We need to compute the change of basis according to the quadrature weights attached to pmat via MatSetNearNullSpace, and this could not be done (at the moment) without some hacking */ 6699b7ab4a40SStefano Zampini if (need_change) { 670088c03ad3SStefano Zampini PC_IS *pcisf; 670188c03ad3SStefano Zampini PC_BDDC *pcbddcf; 670288c03ad3SStefano Zampini PC pcf; 670388c03ad3SStefano Zampini 6704e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 670588c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 670688c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 670788c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 670888c03ad3SStefano Zampini /* hacks */ 670988c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 671072b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 671172b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 671272b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 671372b8c272SStefano Zampini pcisf->n = pcis->n; 671472b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 671588c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 671688c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 671788c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 671888c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 671988c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 672088c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 672172b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 672288c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 672388c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 672472b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 672572b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 672672b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 672772b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 672872b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 672988c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 673072b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 673188c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 673288c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 673388c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 673488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 673588c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 673688c03ad3SStefano Zampini pcf->ops->destroy = NULL; 673788c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 673888c03ad3SStefano Zampini } 67399d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 674091af6908SStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,pcbddc->local_mat,S_j,pcbddc->sub_schurs_exact_schur,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,scaling,pcbddc->adaptive_selection,reuse_solvers,pcbddc->benign_saddle_point,benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_zerodiag_subs,change,change_primal);CHKERRQ(ierr); 674172b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 674272b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 6743ca92afb2SStefano Zampini } 6744d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6745b96c3477SStefano Zampini 6746b96c3477SStefano Zampini /* free adjacency */ 6747b96c3477SStefano Zampini if (free_used_adj) { 6748b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6749b96c3477SStefano Zampini } 6750b96c3477SStefano Zampini PetscFunctionReturn(0); 6751b96c3477SStefano Zampini } 6752b96c3477SStefano Zampini 6753b96c3477SStefano Zampini #undef __FUNCT__ 6754b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 675508122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6756b96c3477SStefano Zampini { 6757b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6758b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6759b96c3477SStefano Zampini PCBDDCGraph graph; 6760b96c3477SStefano Zampini PetscErrorCode ierr; 6761b96c3477SStefano Zampini 6762b96c3477SStefano Zampini PetscFunctionBegin; 6763b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 676408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 67653301b35fSStefano Zampini IS verticesIS,verticescomm; 67663301b35fSStefano Zampini PetscInt vsize,*idxs; 6767b96c3477SStefano Zampini 6768b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 67693301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 67703301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 67713301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 67723301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 67733301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6774b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 67757fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 6776441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 67773301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6778b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6779b96c3477SStefano Zampini } else { 6780b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6781b96c3477SStefano Zampini } 6782e4d548c7SStefano Zampini /* print some info */ 6783e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 6784e4d548c7SStefano Zampini IS vertices; 6785e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 6786e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6787e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 6788e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 6789e4d548c7SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 6790e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6791e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6792e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 6793e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 6794e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 6795e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6796e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6797e4d548c7SStefano Zampini } 6798b96c3477SStefano Zampini 6799b96c3477SStefano Zampini /* sub_schurs init */ 6800b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 6801b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 6802b334f244SStefano Zampini } 6803b334f244SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6804a64f4aa4SStefano Zampini 6805b96c3477SStefano Zampini /* free graph struct */ 680608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6807b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6808b96c3477SStefano Zampini } 6809b96c3477SStefano Zampini PetscFunctionReturn(0); 6810b96c3477SStefano Zampini } 6811fa34dd3eSStefano Zampini 6812fa34dd3eSStefano Zampini #undef __FUNCT__ 6813fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6814fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6815fa34dd3eSStefano Zampini { 6816fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6817fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6818fa34dd3eSStefano Zampini PetscErrorCode ierr; 6819fa34dd3eSStefano Zampini 6820fa34dd3eSStefano Zampini PetscFunctionBegin; 6821fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6822fa34dd3eSStefano Zampini IS zerodiag = NULL; 68234f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6824fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 68254f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 682675c01103SStefano Zampini PetscReal norm; 6827fa34dd3eSStefano Zampini PetscInt i; 6828fa34dd3eSStefano Zampini 6829fa34dd3eSStefano Zampini /* B0 and B0_B */ 6830fa34dd3eSStefano Zampini if (zerodiag) { 6831fa34dd3eSStefano Zampini IS dummy; 6832fa34dd3eSStefano Zampini 68334f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 68344f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6835fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6836fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6837fa34dd3eSStefano Zampini } 6838fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6839fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6840fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6841fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6842fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6843fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6844fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6845fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6846fa34dd3eSStefano Zampini /* S_j */ 6847fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6848fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6849fa34dd3eSStefano Zampini 6850fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6851fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6852fa34dd3eSStefano Zampini /* continuous in primal space */ 6853fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6854fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6855fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6856fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 68574f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 68584f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6859fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6860fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6861fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6862fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6863fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6864fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6865fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6866fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6867fa34dd3eSStefano Zampini 6868fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6869fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6870fa34dd3eSStefano Zampini /* local with Schur */ 6871fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6872fa34dd3eSStefano Zampini if (zerodiag) { 6873fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 68744f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6875fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6876fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6877fa34dd3eSStefano Zampini } 6878fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6879fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6880fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6881fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6882fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6883fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6884fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6885fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6886fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6887fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6888fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6889fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6890fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6891fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6892fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6893fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6894fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6895fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6896fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6897fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6898fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6899fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6900fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6901fa34dd3eSStefano Zampini if (zerodiag) { 6902fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6903fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 69044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6905fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6906fa34dd3eSStefano Zampini } 6907fa34dd3eSStefano Zampini /* BDDC */ 6908fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6909fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6910fa34dd3eSStefano Zampini 6911fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6912fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6913fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6914fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 69154f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 69164f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6917fa34dd3eSStefano Zampini } 69184f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6919fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6920fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6921fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6922fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6923fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6924fa34dd3eSStefano Zampini } 6925fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6926fa34dd3eSStefano Zampini } 6927