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 #undef __FUNCT__ 8669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 9fa23a32eSStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 10669cc0f4SStefano Zampini { 11a198735bSStefano Zampini Mat loc_divudotp; 12fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 13669cc0f4SStefano Zampini ISLocalToGlobalMapping rmap; 14669cc0f4SStefano Zampini IS *faces,*edges; 15669cc0f4SStefano Zampini PetscScalar *vals; 16669cc0f4SStefano Zampini const PetscScalar *array; 17669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 181ae86dd6SStefano Zampini PetscMPIInt rank; 19a198735bSStefano Zampini PetscErrorCode ierr; 20669cc0f4SStefano Zampini 21669cc0f4SStefano Zampini PetscFunctionBegin; 22669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 23669cc0f4SStefano Zampini if (graph->twodim) { 24669cc0f4SStefano Zampini lmaxneighs = 2; 25669cc0f4SStefano Zampini } else { 26669cc0f4SStefano Zampini lmaxneighs = 1; 27669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 28669cc0f4SStefano Zampini const PetscInt *idxs; 29669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 30669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 31669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 32669cc0f4SStefano Zampini } 33669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 34669cc0f4SStefano Zampini } 35669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 36669cc0f4SStefano Zampini maxsize = 0; 37669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 38669cc0f4SStefano Zampini PetscInt nn; 39669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 40669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 41669cc0f4SStefano Zampini } 42669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 43669cc0f4SStefano Zampini PetscInt nn; 44669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 45669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 46669cc0f4SStefano Zampini } 47669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 48669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 49669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 50669cc0f4SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rmap,NULL);CHKERRQ(ierr); 51669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 521ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 53669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 54669cc0f4SStefano Zampini PetscInt first,last; 55669cc0f4SStefano Zampini 56669cc0f4SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],rmap);CHKERRQ(ierr); 57669cc0f4SStefano Zampini /* the near-null space fo BDDC carries information on quadrature weights, 58669cc0f4SStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 59669cc0f4SStefano Zampini and create a suitable set of basis vectors first */ 60669cc0f4SStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 61669cc0f4SStefano Zampini if (i>=first && i < last) { 62669cc0f4SStefano Zampini PetscScalar *data; 63669cc0f4SStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 64669cc0f4SStefano Zampini data[i-first] = 1.; 65669cc0f4SStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 66669cc0f4SStefano Zampini } 67669cc0f4SStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 68669cc0f4SStefano Zampini } 69669cc0f4SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 701ae86dd6SStefano Zampini for (i=0;i<maxneighs;i++) { /* reset vectors */ 711ae86dd6SStefano Zampini PetscInt first,last; 721ae86dd6SStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 731ae86dd6SStefano Zampini if (i>=first && i < last) { 741ae86dd6SStefano Zampini PetscScalar *data; 751ae86dd6SStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 761ae86dd6SStefano Zampini data[i-first] = 0.; 771ae86dd6SStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 781ae86dd6SStefano Zampini } 791ae86dd6SStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 801ae86dd6SStefano Zampini } 81669cc0f4SStefano Zampini /* compute local quad vec */ 82a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 83a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 84669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 85a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 86fa23a32eSStefano Zampini if (vl2l) { 87fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 88fa23a32eSStefano Zampini } else { 89fa23a32eSStefano Zampini vins = v; 90fa23a32eSStefano Zampini } 91fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 92669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 93*9a962809SStefano Zampini 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); 124fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 125fa23a32eSStefano Zampini if (vl2l) { 126fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 127fa23a32eSStefano 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 361*9a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 362*9a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 363a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 364a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 365a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 366a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 367a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 368a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 369a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 370a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 371a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 372a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 373a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 374a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 375059032f7SStefano Zampini if (reuse) { 376a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 3771dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 378059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 379059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 380059032f7SStefano Zampini PetscInt i; 381059032f7SStefano Zampini 382059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 383059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 384059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 385059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 386059032f7SStefano Zampini } 387059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 3881dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 389059032f7SStefano Zampini } 390a3df083aSStefano Zampini ctx->A = pcis->A_IB; 391a3df083aSStefano Zampini ctx->work = work; 392a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 393a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 394a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 395a3df083aSStefano Zampini pcis->A_IB = A_IB; 396a3df083aSStefano Zampini 397a3df083aSStefano Zampini /* A_BI as A_IB^T */ 398a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 399a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 400a3df083aSStefano Zampini pcis->A_BI = A_BI; 401a3df083aSStefano Zampini } else { 4021dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 4031dd7afcfSStefano Zampini PetscFunctionReturn(0); 4041dd7afcfSStefano Zampini } 405a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 406a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 407a3df083aSStefano Zampini pcis->A_IB = ctx->A; 4081dd7afcfSStefano Zampini ctx->A = NULL; 4091dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 4101dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 4111dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 4121dd7afcfSStefano Zampini if (ctx->free) { 413059032f7SStefano Zampini PetscInt i; 4141dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 415059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 416059032f7SStefano Zampini } 417059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 418059032f7SStefano Zampini } 419a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 420a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 421a3df083aSStefano Zampini } 422a3df083aSStefano Zampini PetscFunctionReturn(0); 423a3df083aSStefano Zampini } 424a3df083aSStefano Zampini 425a3df083aSStefano Zampini /* used just in bddc debug mode */ 426a3df083aSStefano Zampini #undef __FUNCT__ 427a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 428a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 429a3df083aSStefano Zampini { 430a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 431a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 432a3df083aSStefano Zampini Mat An; 433a3df083aSStefano Zampini PetscErrorCode ierr; 434a3df083aSStefano Zampini 435a3df083aSStefano Zampini PetscFunctionBegin; 436a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 437a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 438a3df083aSStefano Zampini if (is1) { 439a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 440a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 441a3df083aSStefano Zampini } else { 442a3df083aSStefano Zampini *B = An; 443a3df083aSStefano Zampini } 444a3df083aSStefano Zampini PetscFunctionReturn(0); 445a3df083aSStefano Zampini } 446a3df083aSStefano Zampini 4471cf9b237SStefano Zampini /* TODO: add reuse flag */ 4481cf9b237SStefano Zampini #undef __FUNCT__ 4491cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 4501cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 4511cf9b237SStefano Zampini { 4521cf9b237SStefano Zampini Mat Bt; 4531cf9b237SStefano Zampini PetscScalar *a,*bdata; 4541cf9b237SStefano Zampini const PetscInt *ii,*ij; 4551cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 4561cf9b237SStefano Zampini PetscBool flg_row; 4571cf9b237SStefano Zampini PetscErrorCode ierr; 4581cf9b237SStefano Zampini 4591cf9b237SStefano Zampini PetscFunctionBegin; 4601cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 4611cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 4621cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 4631cf9b237SStefano Zampini nnz = n; 4641cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 4651cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 4661cf9b237SStefano Zampini } 4671cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 4681cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 4691cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 4701cf9b237SStefano Zampini nnz = 0; 4711cf9b237SStefano Zampini bii[0] = 0; 4721cf9b237SStefano Zampini for (i=0;i<n;i++) { 4731cf9b237SStefano Zampini PetscInt j; 4741cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 4751cf9b237SStefano Zampini PetscScalar entry = a[j]; 4761cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 4771cf9b237SStefano Zampini bij[nnz] = ij[j]; 4781cf9b237SStefano Zampini bdata[nnz] = entry; 4791cf9b237SStefano Zampini nnz++; 4801cf9b237SStefano Zampini } 4811cf9b237SStefano Zampini } 4821cf9b237SStefano Zampini bii[i+1] = nnz; 4831cf9b237SStefano Zampini } 4841cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 4851cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 4861cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 4871cf9b237SStefano Zampini { 4881cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 4891cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 4901cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 4911cf9b237SStefano Zampini } 4921cf9b237SStefano Zampini *B = Bt; 4931cf9b237SStefano Zampini PetscFunctionReturn(0); 4941cf9b237SStefano Zampini } 4951cf9b237SStefano Zampini 496674ae819SStefano Zampini #undef __FUNCT__ 4974f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 4984f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 4994f1b2e48SStefano Zampini { 5004f1b2e48SStefano Zampini Mat B; 5014f1b2e48SStefano Zampini IS is_dummy,*cc_n; 5024f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 5034f1b2e48SStefano Zampini PCBDDCGraph graph; 5044f1b2e48SStefano Zampini PetscInt i,n; 5054f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 5064f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 5074f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 5084f1b2e48SStefano Zampini PetscErrorCode ierr; 5094f1b2e48SStefano Zampini 5104f1b2e48SStefano Zampini PetscFunctionBegin; 51163c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 51263c961adSStefano Zampini *ncc = 0; 51363c961adSStefano Zampini *cc = NULL; 51463c961adSStefano Zampini PetscFunctionReturn(0); 51563c961adSStefano Zampini } 5164f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 5174f1b2e48SStefano Zampini if (!isseqaij && filter) { 5181cf9b237SStefano Zampini PetscBool isseqdense; 5191cf9b237SStefano Zampini 5201cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 5211cf9b237SStefano Zampini if (!isseqdense) { 5224f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 5231cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 5241cf9b237SStefano Zampini PetscScalar *array; 5251cf9b237SStefano Zampini PetscReal chop=1.e-6; 5261cf9b237SStefano Zampini 5271cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 5281cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 5291cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 5301cf9b237SStefano Zampini for (i=0;i<n;i++) { 5311cf9b237SStefano Zampini PetscInt j; 5321cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 5331cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 5341cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 5351cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 5361cf9b237SStefano Zampini } 5371cf9b237SStefano Zampini } 5381cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 5399d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 5401cf9b237SStefano Zampini } 5414f1b2e48SStefano Zampini } else { 5424f1b2e48SStefano Zampini B = A; 5434f1b2e48SStefano Zampini } 5444f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5454f1b2e48SStefano Zampini 5464f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 5474f1b2e48SStefano Zampini if (filter) { 5484f1b2e48SStefano Zampini PetscScalar *data; 5494f1b2e48SStefano Zampini PetscInt j,cum; 5504f1b2e48SStefano Zampini 5514f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 5524f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 5534f1b2e48SStefano Zampini cum = 0; 5544f1b2e48SStefano Zampini for (i=0;i<n;i++) { 5554f1b2e48SStefano Zampini PetscInt t; 5564f1b2e48SStefano Zampini 5574f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 5584f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 5594f1b2e48SStefano Zampini continue; 5604f1b2e48SStefano Zampini } 5614f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 5624f1b2e48SStefano Zampini } 5634f1b2e48SStefano Zampini t = xadj_filtered[i]; 5644f1b2e48SStefano Zampini xadj_filtered[i] = cum; 5654f1b2e48SStefano Zampini cum += t; 5664f1b2e48SStefano Zampini } 5674f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 5684f1b2e48SStefano Zampini } else { 5694f1b2e48SStefano Zampini xadj_filtered = NULL; 5704f1b2e48SStefano Zampini adjncy_filtered = NULL; 5714f1b2e48SStefano Zampini } 5724f1b2e48SStefano Zampini 5734f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 5744f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 5754f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 5764f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 5774f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 5784f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 5794f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 5804f1b2e48SStefano Zampini if (xadj_filtered) { 5814f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 5824f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 5834f1b2e48SStefano Zampini } else { 5844f1b2e48SStefano Zampini graph->xadj = xadj; 5854f1b2e48SStefano Zampini graph->adjncy = adjncy; 5864f1b2e48SStefano Zampini } 5874f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 5884f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5894f1b2e48SStefano Zampini /* partial clean up */ 5904f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 5914f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5921cf9b237SStefano Zampini if (A != B) { 5934f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 5944f1b2e48SStefano Zampini } 5954f1b2e48SStefano Zampini 5964f1b2e48SStefano Zampini /* get back data */ 5971cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 5981cf9b237SStefano Zampini if (cc) { 5994f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 6004f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 6014f1b2e48SStefano 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); 6024f1b2e48SStefano Zampini } 6034f1b2e48SStefano Zampini *cc = cc_n; 6041cf9b237SStefano Zampini } 6054f1b2e48SStefano Zampini /* clean up graph */ 6064f1b2e48SStefano Zampini graph->xadj = 0; 6074f1b2e48SStefano Zampini graph->adjncy = 0; 6084f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6094f1b2e48SStefano Zampini PetscFunctionReturn(0); 6104f1b2e48SStefano Zampini } 6114f1b2e48SStefano Zampini 6124f1b2e48SStefano Zampini #undef __FUNCT__ 6135408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 6145408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 6155408967cSStefano Zampini { 6165408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6175408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 618dee84bffSStefano Zampini IS dirIS = NULL; 6194f1b2e48SStefano Zampini PetscInt i; 6205408967cSStefano Zampini PetscErrorCode ierr; 6215408967cSStefano Zampini 6225408967cSStefano Zampini PetscFunctionBegin; 623dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 6245408967cSStefano Zampini if (zerodiag) { 6255408967cSStefano Zampini Mat A; 6265408967cSStefano Zampini Vec vec3_N; 6275408967cSStefano Zampini PetscScalar *vals; 6285408967cSStefano Zampini const PetscInt *idxs; 629d12d3064SStefano Zampini PetscInt nz,*count; 6305408967cSStefano Zampini 6315408967cSStefano Zampini /* p0 */ 6325408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 6335408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 6345408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 6355408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 6364f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 6375408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6385408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6395408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6405408967cSStefano Zampini /* v_I */ 6415408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 6425408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 6435408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6445408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 6455408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 6465408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 6475408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6485408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 6495408967cSStefano Zampini if (dirIS) { 6505408967cSStefano Zampini PetscInt n; 6515408967cSStefano Zampini 6525408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 6535408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 6545408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 6555408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6565408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 6575408967cSStefano Zampini } 6585408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 6595408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 6605408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 6615408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 662669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 6635408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 6645408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 665*9a962809SStefano Zampini if (PetscAbsScalar(vals[0]) > 1.e-1) 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])); 6665408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6675408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 668d12d3064SStefano Zampini 669d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 670d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 671d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 672d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 673d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 674d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 675*9a962809SStefano Zampini for (i=0;i<nz;i++) if (count[idxs[i]]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 676d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 677d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 6785408967cSStefano Zampini } 679dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 6805408967cSStefano Zampini 6815408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 6825408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 6834f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 6845408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 6854f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 6865408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 687*9a962809SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) 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); 6885408967cSStefano Zampini PetscFunctionReturn(0); 6895408967cSStefano Zampini } 6905408967cSStefano Zampini 6915408967cSStefano Zampini #undef __FUNCT__ 692339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 693339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 694339f8db1SStefano Zampini { 695339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6964f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 697b0f5fe93SStefano Zampini PetscInt nz,n; 6981f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 6994f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 700339f8db1SStefano Zampini PetscErrorCode ierr; 701339f8db1SStefano Zampini 702339f8db1SStefano Zampini PetscFunctionBegin; 7039f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 7049f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 705a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 706a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 707a3df083aSStefano Zampini } 708a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 709a3df083aSStefano Zampini pcbddc->benign_n = 0; 7101ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 7114f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 7124f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 7134f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 7141ae86dd6SStefano Zampini since the local Schur complements are already SPD 7154f1b2e48SStefano Zampini */ 7164f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 7174f1b2e48SStefano Zampini have_null = PETSC_TRUE; 71840fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 7194f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 7204f1b2e48SStefano Zampini 7214f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 7224f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 7234f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 7244f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 725ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 72640fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 72740fa8d13SStefano Zampini if (!sorted) { 72840fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 72940fa8d13SStefano Zampini } 73040fa8d13SStefano Zampini } else { 73140fa8d13SStefano Zampini pressures = NULL; 73240fa8d13SStefano Zampini } 73397d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 73497d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 73527b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 73697d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 737339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 738339f8db1SStefano Zampini if (!sorted) { 739339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 740339f8db1SStefano Zampini } 741339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 7424f1b2e48SStefano Zampini if (!nz) { 7434f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 7444f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 74540fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 74640fa8d13SStefano Zampini } 7474f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 7484f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 7494f1b2e48SStefano Zampini zerodiag_subs = NULL; 7504f1b2e48SStefano Zampini pcbddc->benign_n = 0; 7511f4df5f7SStefano Zampini n_interior_dofs = 0; 7521f4df5f7SStefano Zampini interior_dofs = NULL; 7531f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 7541f4df5f7SStefano Zampini PetscInt n,i,j; 7551f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 7561f4df5f7SStefano Zampini PetscInt *iwork; 7571f4df5f7SStefano Zampini 7581f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 7591f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 7601f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 7611f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 7621f4df5f7SStefano Zampini for (i=0;i<n_neigh;i++) 7631f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 7641f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 7651f4df5f7SStefano Zampini for (i=0;i<n;i++) 7661f4df5f7SStefano Zampini if (!iwork[i]) 7671f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 7681f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 7691f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 7701f4df5f7SStefano Zampini } 7714f1b2e48SStefano Zampini if (has_null_pressures) { 7724f1b2e48SStefano Zampini IS *subs; 7731f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 7741f4df5f7SStefano Zampini const PetscInt *idxs; 7751f4df5f7SStefano Zampini PetscScalar *array; 7761f4df5f7SStefano Zampini Vec *work; 7771f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 7784f1b2e48SStefano Zampini 7794f1b2e48SStefano Zampini subs = pcbddc->local_subs; 7804f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 7811f4df5f7SStefano 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) */ 7821f4df5f7SStefano Zampini if (pcbddc->current_level) { 7831f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 7841f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 7851f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 7861f4df5f7SStefano Zampini /* work[0] = 1_p */ 7871f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 7881f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 7891f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 7901f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 7911f4df5f7SStefano Zampini /* work[0] = 1_v */ 7921f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 7931f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 7941f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 7951f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 7961f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 7971f4df5f7SStefano Zampini } 7984f1b2e48SStefano Zampini if (nsubs > 1) { 7994f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 8004f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 8014f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 8024f1b2e48SStefano Zampini IS t_zerodiag_subs; 8034f1b2e48SStefano Zampini PetscInt nl; 8044f1b2e48SStefano Zampini 8054f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 8064f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 8074f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 8084f1b2e48SStefano Zampini if (nl) { 8094f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 8104f1b2e48SStefano Zampini 8111f4df5f7SStefano Zampini if (pcbddc->current_level) { 8121f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 8131f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 8141f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 8151f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 8161f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 8171f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 8181f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 8191f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 8201f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 8211f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 8221f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 8231f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 8241f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 8251f4df5f7SStefano Zampini valid = PETSC_FALSE; 8261f4df5f7SStefano Zampini break; 8271f4df5f7SStefano Zampini } 8281f4df5f7SStefano Zampini } 8291f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 8301f4df5f7SStefano Zampini } 8311f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 8321f4df5f7SStefano Zampini IS t_bc; 8331f4df5f7SStefano Zampini PetscInt nzb; 8341f4df5f7SStefano Zampini 8351f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 8361f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 8371f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 8381f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 8391f4df5f7SStefano Zampini } 8401f4df5f7SStefano Zampini if (valid && pressures) { 8414f1b2e48SStefano Zampini IS t_pressure_subs; 8424f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 8434f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 8444f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 8454f1b2e48SStefano Zampini } 8464f1b2e48SStefano Zampini if (valid) { 8474f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 8484f1b2e48SStefano Zampini pcbddc->benign_n++; 8494f1b2e48SStefano Zampini } else { 8504f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 8514f1b2e48SStefano Zampini } 8524f1b2e48SStefano Zampini } 8534f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 8544f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 8554f1b2e48SStefano Zampini } 8564f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 8574f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 8581f4df5f7SStefano Zampini 8591f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 8601f4df5f7SStefano Zampini PetscInt nzb; 8611f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 8621f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 8631f4df5f7SStefano Zampini } 8641f4df5f7SStefano Zampini if (valid && pressures) { 8654f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 8664f1b2e48SStefano Zampini } 8671f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 8681f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 8691f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 8701f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 8711f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 8721f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 8731f4df5f7SStefano Zampini valid = PETSC_FALSE; 8741f4df5f7SStefano Zampini break; 8751f4df5f7SStefano Zampini } 8761f4df5f7SStefano Zampini } 8771f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 8781f4df5f7SStefano Zampini } 8794f1b2e48SStefano Zampini if (valid) { 8804f1b2e48SStefano Zampini pcbddc->benign_n = 1; 881ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 8824f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 8834f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 8844f1b2e48SStefano Zampini } 8854f1b2e48SStefano Zampini } 8861f4df5f7SStefano Zampini if (pcbddc->current_level) { 8871f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 8884f1b2e48SStefano Zampini } 8891f4df5f7SStefano Zampini } 8901f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 8914f1b2e48SStefano Zampini 8924f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 893b9b0e38cSStefano Zampini PetscInt n; 894b9b0e38cSStefano Zampini 8954f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 8964f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 897b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 898b9b0e38cSStefano Zampini if (n) { 8994f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 9004f1b2e48SStefano Zampini have_null = PETSC_FALSE; 9014f1b2e48SStefano Zampini } 902b9b0e38cSStefano Zampini } 9034f1b2e48SStefano Zampini 9044f1b2e48SStefano Zampini /* final check for null pressures */ 9054f1b2e48SStefano Zampini if (zerodiag && pressures) { 9064f1b2e48SStefano Zampini PetscInt nz,np; 9074f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 9084f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 9094f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 9104f1b2e48SStefano Zampini } 9114f1b2e48SStefano Zampini 9124f1b2e48SStefano Zampini if (recompute_zerodiag) { 9134f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 9144f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 9154f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 9164f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 9174f1b2e48SStefano Zampini } else { 9184f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 9194f1b2e48SStefano Zampini 9204f1b2e48SStefano Zampini nzn = 0; 9214f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 9224f1b2e48SStefano Zampini PetscInt ns; 9234f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 9244f1b2e48SStefano Zampini nzn += ns; 9254f1b2e48SStefano Zampini } 9264f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 9274f1b2e48SStefano Zampini nzn = 0; 9284f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 9294f1b2e48SStefano Zampini PetscInt ns,*idxs; 9304f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 9314f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 9324f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 9334f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 9344f1b2e48SStefano Zampini nzn += ns; 9354f1b2e48SStefano Zampini } 9364f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 9374f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 9384f1b2e48SStefano Zampini } 9394f1b2e48SStefano Zampini have_null = PETSC_FALSE; 9404f1b2e48SStefano Zampini } 9414f1b2e48SStefano Zampini 942669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 943a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 944a198735bSStefano Zampini Mat A,loc_divudotp; 945a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 946a198735bSStefano Zampini IS row,col,isused = NULL; 947a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 948a198735bSStefano Zampini 9491f4df5f7SStefano Zampini if (pressures) { 9501f4df5f7SStefano Zampini isused = pressures; 9511f4df5f7SStefano Zampini } else { 9521f4df5f7SStefano Zampini isused = zerodiag; 9531f4df5f7SStefano Zampini } 954a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 955669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 9561ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 9571ae86dd6SStefano 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"); 958a198735bSStefano Zampini n_isused = 0; 959a198735bSStefano Zampini if (isused) { 960a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 961a198735bSStefano Zampini } 962a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 963a198735bSStefano Zampini st = st-n_isused; 9641ae86dd6SStefano Zampini if (n) { 965a198735bSStefano Zampini const PetscInt *gidxs; 966a198735bSStefano Zampini 967a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 968a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 969a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 970a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 971a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 972a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 9731ae86dd6SStefano Zampini } else { 974a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 975a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 976a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 977a198735bSStefano Zampini } 978a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 979a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 980a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 981a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 982a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 983a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 984a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 985a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 986a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 987a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 988a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 989a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 990a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 991a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 9921ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9931ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9941ae86dd6SStefano Zampini } 995b3afcdbeSStefano Zampini 996b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 9974f1b2e48SStefano Zampini if (has_null_pressures) { 9984f1b2e48SStefano Zampini IS zerodiagc; 9994f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 10004f1b2e48SStefano Zampini PetscInt i,s,*nnz; 10014f1b2e48SStefano Zampini 10024f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 1003339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 1004339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 1005339f8db1SStefano Zampini /* local change of basis for pressures */ 1006339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 100797d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 1008339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 1009339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1010339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 10114f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 10124f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 10134f1b2e48SStefano Zampini PetscInt nzs,j; 10144f1b2e48SStefano Zampini 10154f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 10164f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 10174f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 10184f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 10194f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 10204f1b2e48SStefano Zampini } 1021339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 1022339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1023339f8db1SStefano Zampini /* set identity on velocities */ 1024339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 1025339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 1026339f8db1SStefano Zampini } 10274f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 10284f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 10299f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 10304f1b2e48SStefano 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); 1031339f8db1SStefano Zampini /* set change on pressures */ 10324f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 10334f1b2e48SStefano Zampini PetscScalar *array; 10344f1b2e48SStefano Zampini PetscInt nzs; 10354f1b2e48SStefano Zampini 10364f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 10374f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 10384f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 1039339f8db1SStefano Zampini PetscScalar vals[2]; 1040339f8db1SStefano Zampini PetscInt cols[2]; 1041339f8db1SStefano Zampini 1042339f8db1SStefano Zampini cols[0] = idxs[i]; 10434f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 1044339f8db1SStefano Zampini vals[0] = 1.; 1045b0f5fe93SStefano Zampini vals[1] = 1.; 10464f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 1047339f8db1SStefano Zampini } 10484f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 10494f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 10504f1b2e48SStefano Zampini array[nzs-1] = 1.; 10514f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 10524f1b2e48SStefano Zampini /* store local idxs for p0 */ 10534f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 10544f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 1055339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 10564f1b2e48SStefano Zampini } 1057339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1058339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1059a3df083aSStefano Zampini /* project if needed */ 1060a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 10611dd7afcfSStefano Zampini Mat M; 10621dd7afcfSStefano Zampini 10631dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 1064339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 10651dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 10661dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1067a3df083aSStefano Zampini } 10684f1b2e48SStefano Zampini /* store global idxs for p0 */ 10694f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1070339f8db1SStefano Zampini } 1071ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 10724f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 1073b0f5fe93SStefano Zampini 1074b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 1075b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 107627b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 107727b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1078339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 1079339f8db1SStefano Zampini PetscFunctionReturn(0); 1080339f8db1SStefano Zampini } 1081339f8db1SStefano Zampini 1082339f8db1SStefano Zampini #undef __FUNCT__ 1083015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 1084015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 1085efc2fbd9SStefano Zampini { 1086efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1087de9d7bd0SStefano Zampini PetscScalar *array; 1088efc2fbd9SStefano Zampini PetscErrorCode ierr; 1089efc2fbd9SStefano Zampini 1090efc2fbd9SStefano Zampini PetscFunctionBegin; 1091efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 1092efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 10934f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1094efc2fbd9SStefano Zampini } 1095de9d7bd0SStefano Zampini if (get) { 1096efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 10974f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 10984f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 1099efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 1100de9d7bd0SStefano Zampini } else { 1101de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 1102de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1103de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1104de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 1105efc2fbd9SStefano Zampini } 1106efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1107efc2fbd9SStefano Zampini } 1108efc2fbd9SStefano Zampini 1109efc2fbd9SStefano Zampini #undef __FUNCT__ 1110c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 1111c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 1112c263805aSStefano Zampini { 1113c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1114c263805aSStefano Zampini PetscErrorCode ierr; 1115c263805aSStefano Zampini 1116c263805aSStefano Zampini PetscFunctionBegin; 1117c263805aSStefano Zampini /* TODO: add error checking 1118c263805aSStefano Zampini - avoid nested pop (or push) calls. 1119c263805aSStefano Zampini - cannot push before pop. 11201c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 1121c263805aSStefano Zampini */ 11224f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1123efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1124efc2fbd9SStefano Zampini } 1125c263805aSStefano Zampini if (pop) { 1126a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 11274f1b2e48SStefano Zampini IS is_p0; 11284f1b2e48SStefano Zampini MatReuse reuse; 1129c263805aSStefano Zampini 1130c263805aSStefano Zampini /* extract B_0 */ 11314f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 11324f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 11334f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 11344f1b2e48SStefano Zampini } 11354f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 11364f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 1137c263805aSStefano Zampini /* remove rows and cols from local problem */ 1138c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 113997d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 11404f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 11414f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 1142a3df083aSStefano Zampini } else { 1143a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1144a3df083aSStefano Zampini PetscScalar *vals; 1145a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 1146a3df083aSStefano Zampini 1147a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 1148a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 1149a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 11500b5adadeSStefano Zampini PetscInt *nnz; 1151a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 1152a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 1153a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1154331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 1155331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1156331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 1157331e053bSStefano Zampini nnz[i] = n - nnz[i]; 1158331e053bSStefano Zampini } 1159331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 1160331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1161331e053bSStefano Zampini } 1162a3df083aSStefano Zampini 1163a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1164a3df083aSStefano Zampini PetscScalar *array; 1165a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 1166a3df083aSStefano Zampini 1167a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 1168a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1169a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1170a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 1171a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1172a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 1173a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 1174a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 1175a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 1176a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 1177a3df083aSStefano Zampini cum = 0; 1178a3df083aSStefano Zampini for (j=0;j<n;j++) { 117922db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 1180a3df083aSStefano Zampini vals[cum] = array[j]; 1181a3df083aSStefano Zampini idxs_ins[cum] = j; 1182a3df083aSStefano Zampini cum++; 1183a3df083aSStefano Zampini } 1184a3df083aSStefano Zampini } 1185a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 1186a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 1187a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1188a3df083aSStefano Zampini } 1189a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1190a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1191a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 1192a3df083aSStefano Zampini } 1193c263805aSStefano Zampini } else { /* push */ 1194a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 11954f1b2e48SStefano Zampini PetscInt i; 11964f1b2e48SStefano Zampini 11974f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 11984f1b2e48SStefano Zampini PetscScalar *B0_vals; 11994f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 12004f1b2e48SStefano Zampini 12014f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 12024f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 12037b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 12044f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 12054f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 12064f1b2e48SStefano Zampini } 1207c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1208c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1209a3df083aSStefano Zampini } else { 1210a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 1211a3df083aSStefano Zampini } 1212c263805aSStefano Zampini } 1213c263805aSStefano Zampini PetscFunctionReturn(0); 1214c263805aSStefano Zampini } 1215c263805aSStefano Zampini 1216c263805aSStefano Zampini #undef __FUNCT__ 1217b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 121808122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 1219b1b3d7a2SStefano Zampini { 1220b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 122108122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 122208122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 122308122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 122408122e43SStefano Zampini PetscScalar *work,lwork; 122508122e43SStefano Zampini PetscScalar *St,*S,*eigv; 122608122e43SStefano Zampini PetscScalar *Sarray,*Starray; 122708122e43SStefano Zampini PetscReal *eigs,thresh; 12281b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 1229f6f667cfSStefano Zampini PetscBool allocated_S_St; 123008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 123108122e43SStefano Zampini PetscReal *rwork; 123208122e43SStefano Zampini #endif 1233b1b3d7a2SStefano Zampini PetscErrorCode ierr; 1234b1b3d7a2SStefano Zampini 1235b1b3d7a2SStefano Zampini PetscFunctionBegin; 1236b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 1237af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 1238af25d912SStefano 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); 123906a4e24aSStefano Zampini 1240fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1241fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1242fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1243fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 12441575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1245fd14bc51SStefano Zampini } 1246fd14bc51SStefano Zampini 1247e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 1248e496cd5dSStefano 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); 1249e496cd5dSStefano Zampini } 1250e496cd5dSStefano Zampini 125108122e43SStefano Zampini /* max size of subsets */ 125208122e43SStefano Zampini mss = 0; 125308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 125408122e43SStefano Zampini PetscInt subset_size; 1255862806e4SStefano Zampini 125608122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 125708122e43SStefano Zampini mss = PetscMax(mss,subset_size); 125808122e43SStefano Zampini } 125908122e43SStefano Zampini 126008122e43SStefano Zampini /* min/max and threshold */ 126108122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 1262f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 126308122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 1264f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 1265f6f667cfSStefano Zampini if (nmin) { 1266f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 1267f6f667cfSStefano Zampini } 126808122e43SStefano Zampini 126908122e43SStefano Zampini /* allocate lapack workspace */ 127008122e43SStefano Zampini cum = cum2 = 0; 127108122e43SStefano Zampini maxneigs = 0; 127208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 127308122e43SStefano Zampini PetscInt n,subset_size; 1274f6f667cfSStefano Zampini 127508122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 127608122e43SStefano Zampini n = PetscMin(subset_size,nmax); 12779162d606SStefano Zampini cum += subset_size; 12789162d606SStefano Zampini cum2 += subset_size*n; 127908122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 128008122e43SStefano Zampini } 128108122e43SStefano Zampini if (mss) { 12829ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 128308122e43SStefano Zampini PetscBLASInt B_itype = 1; 128408122e43SStefano Zampini PetscBLASInt B_N = mss; 12854c6709b3SStefano Zampini PetscReal zero = 0.0; 12864c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 128708122e43SStefano Zampini 128808122e43SStefano Zampini B_lwork = -1; 128908122e43SStefano Zampini S = NULL; 129008122e43SStefano Zampini St = NULL; 1291a58a30b4SStefano Zampini eigs = NULL; 1292a58a30b4SStefano Zampini eigv = NULL; 1293a58a30b4SStefano Zampini B_iwork = NULL; 1294a58a30b4SStefano Zampini B_ifail = NULL; 1295d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1296d1710679SStefano Zampini rwork = NULL; 1297d1710679SStefano Zampini #endif 12988bec7fa6SStefano Zampini thresh = 1.0; 129908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 130008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 130108122e43SStefano 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)); 130208122e43SStefano Zampini #else 130308122e43SStefano 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)); 130408122e43SStefano Zampini #endif 130508122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 130608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 130708122e43SStefano Zampini } else { 130808122e43SStefano Zampini /* TODO */ 130908122e43SStefano Zampini } 131008122e43SStefano Zampini } else { 131108122e43SStefano Zampini lwork = 0; 131208122e43SStefano Zampini } 131308122e43SStefano Zampini 131408122e43SStefano Zampini nv = 0; 1315d62866d3SStefano 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) */ 1316d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 131708122e43SStefano Zampini } 13184c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 1319f6f667cfSStefano Zampini if (allocated_S_St) { 1320f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 1321f6f667cfSStefano Zampini } 1322f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 132308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 132408122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 132508122e43SStefano Zampini #endif 13269162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 13279162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 13289162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 132908122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 13309162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 133108122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 133208122e43SStefano Zampini 133308122e43SStefano Zampini maxneigs = 0; 133472b8c272SStefano Zampini cum = cumarray = 0; 13359162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 13369162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 1337d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 133808122e43SStefano Zampini const PetscInt *idxs; 133908122e43SStefano Zampini 1340d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 134108122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 134208122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 134308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 134408122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 13459162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 13469162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 134708122e43SStefano Zampini } 1348d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 134908122e43SStefano Zampini } 135008122e43SStefano Zampini 135108122e43SStefano Zampini if (mss) { /* multilevel */ 135208122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 135308122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 135408122e43SStefano Zampini } 135508122e43SStefano Zampini 1356ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 135708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 135808122e43SStefano Zampini const PetscInt *idxs; 13599d54b7f4SStefano Zampini PetscReal upper,lower; 1360862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 136108122e43SStefano Zampini PetscBLASInt B_N; 1362aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 136308122e43SStefano Zampini 13649d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 13659d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 13669d54b7f4SStefano Zampini lower = thresh; 13679d54b7f4SStefano Zampini } else { 13689d54b7f4SStefano Zampini upper = 1./thresh; 13699d54b7f4SStefano Zampini lower = 0.; 13709d54b7f4SStefano Zampini } 1371862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 1372ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 1373f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 1374f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 13759ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 1376aff50787SStefano Zampini PetscInt j,k; 1377aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 1378aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 1379aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 138008122e43SStefano Zampini } 138108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 1382aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 1383aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 1384aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 1385aff50787SStefano Zampini } 138608122e43SStefano Zampini } 138708122e43SStefano Zampini } else { 138808122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 138908122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 139008122e43SStefano Zampini } 13918bec7fa6SStefano Zampini } else { 1392f6f667cfSStefano Zampini S = Sarray + cumarray; 1393f6f667cfSStefano Zampini St = Starray + cumarray; 13948bec7fa6SStefano Zampini } 1395aff50787SStefano Zampini /* see if we can save some work */ 1396b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 1397aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1398aff50787SStefano Zampini } 1399aff50787SStefano Zampini 1400b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 1401aff50787SStefano Zampini B_neigs = 0; 1402aff50787SStefano Zampini } else { 14039ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 140408122e43SStefano Zampini PetscBLASInt B_itype = 1; 1405f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 14064c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 14079552c7c7SStefano Zampini PetscInt nmin_s; 1408b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 140908122e43SStefano Zampini 1410fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 14118bec7fa6SStefano 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]]); 1412fd14bc51SStefano Zampini } 1413d16cbb6bSStefano Zampini 1414b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 1415b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 1416b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 1417b7ab4a40SStefano Zampini } 1418b7ab4a40SStefano Zampini 141908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1420b7ab4a40SStefano Zampini if (compute_range) { 1421d16cbb6bSStefano Zampini 1422d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 142308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 14249d54b7f4SStefano 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)); 142508122e43SStefano Zampini #else 14269d54b7f4SStefano 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)); 142708122e43SStefano Zampini #endif 1428b7ab4a40SStefano Zampini } else if (!same_data) { 1429d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1430d16cbb6bSStefano Zampini B_IL = 1; 1431d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 14329d54b7f4SStefano 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)); 1433d16cbb6bSStefano Zampini #else 14349d54b7f4SStefano 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)); 1435d16cbb6bSStefano Zampini #endif 1436b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 1437b7ab4a40SStefano Zampini PetscInt k; 1438b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 1439b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 1440b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 1441b7ab4a40SStefano Zampini nmin = nmax; 1442b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 1443b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 1444b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 1445b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 1446b7ab4a40SStefano Zampini } 1447d16cbb6bSStefano Zampini } 144808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 144908122e43SStefano Zampini if (B_ierr) { 14506c4ed002SBarry 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); 14516c4ed002SBarry 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); 14526c4ed002SBarry 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); 145308122e43SStefano Zampini } 145408122e43SStefano Zampini 145508122e43SStefano Zampini if (B_neigs > nmax) { 1456fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1457fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1458fd14bc51SStefano Zampini } 14599d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 146008122e43SStefano Zampini B_neigs = nmax; 146108122e43SStefano Zampini } 146208122e43SStefano Zampini 14639552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 14649552c7c7SStefano Zampini if (B_neigs < nmin_s) { 146508122e43SStefano Zampini PetscBLASInt B_neigs2; 146608122e43SStefano Zampini 14679d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1468f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 14699d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 14709d54b7f4SStefano Zampini } else { 14719d54b7f4SStefano Zampini B_IL = B_neigs + 1; 14729d54b7f4SStefano Zampini B_IU = nmin_s; 14739d54b7f4SStefano Zampini } 1474fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1475fd14bc51SStefano 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); 1476fd14bc51SStefano Zampini } 14779ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 14781ae86dd6SStefano Zampini PetscInt j,k; 147908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 14801ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 14811ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 14821ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 148308122e43SStefano Zampini } 148408122e43SStefano Zampini } 148508122e43SStefano Zampini } else { 148608122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 148708122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 148808122e43SStefano Zampini } 148908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 149008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 14919d54b7f4SStefano 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)); 149208122e43SStefano Zampini #else 14939d54b7f4SStefano 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)); 149408122e43SStefano Zampini #endif 149508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 149608122e43SStefano Zampini B_neigs += B_neigs2; 149708122e43SStefano Zampini } 149808122e43SStefano Zampini if (B_ierr) { 14996c4ed002SBarry 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); 15006c4ed002SBarry 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); 15016c4ed002SBarry 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); 150208122e43SStefano Zampini } 1503fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1504ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 150508122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 150608122e43SStefano Zampini if (eigs[j] == 0.0) { 1507ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 150808122e43SStefano Zampini } else { 15099d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1510ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 15119d54b7f4SStefano Zampini } else { 15129d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 15139d54b7f4SStefano Zampini } 1514fd14bc51SStefano Zampini } 151508122e43SStefano Zampini } 151608122e43SStefano Zampini } 151708122e43SStefano Zampini } else { 151808122e43SStefano Zampini /* TODO */ 151908122e43SStefano Zampini } 1520aff50787SStefano Zampini } 15216c3e6151SStefano Zampini /* change the basis back to the original one */ 15226c3e6151SStefano Zampini if (sub_schurs->change) { 152372b8c272SStefano Zampini Mat change,phi,phit; 15246c3e6151SStefano Zampini 15256c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 15266c3e6151SStefano Zampini PetscInt ii; 15276c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 15286c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 15296c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 15306c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 15316c3e6151SStefano Zampini } 15326c3e6151SStefano Zampini } 15336c3e6151SStefano Zampini } 153472b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 15356c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 153672b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 15376c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 15386c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 15396c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 15406c3e6151SStefano Zampini } 15418bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 15428bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 15439162d606SStefano Zampini if (B_neigs) { 15449162d606SStefano 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); 1545fd14bc51SStefano Zampini 1546fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 15479552c7c7SStefano Zampini PetscInt ii; 15489552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1549ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 15509552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1551ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1552ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1553ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1554ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1555ac47001eSStefano Zampini #else 1556ac47001eSStefano 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); 1557ac47001eSStefano Zampini #endif 15589552c7c7SStefano Zampini } 15599552c7c7SStefano Zampini } 1560fd14bc51SStefano Zampini } 15619162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 15629162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 15639162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 15649162d606SStefano Zampini cum++; 156508122e43SStefano Zampini } 156608122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 156708122e43SStefano Zampini /* shift for next computation */ 156808122e43SStefano Zampini cumarray += subset_size*subset_size; 156908122e43SStefano Zampini } 1570fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1571fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1572fd14bc51SStefano Zampini } 157308122e43SStefano Zampini 157408122e43SStefano Zampini if (mss) { 157508122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 157608122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1577f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1578f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1579f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 158008122e43SStefano Zampini } 1581f6f667cfSStefano Zampini if (allocated_S_St) { 1582f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1583f6f667cfSStefano Zampini } 1584f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 158508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 158608122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 158708122e43SStefano Zampini #endif 158808122e43SStefano Zampini if (pcbddc->dbg_flag) { 15891b968477SStefano Zampini PetscInt maxneigs_r; 1590b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 15919b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 159208122e43SStefano Zampini } 159308122e43SStefano Zampini PetscFunctionReturn(0); 159408122e43SStefano Zampini } 1595b1b3d7a2SStefano Zampini 1596674ae819SStefano Zampini #undef __FUNCT__ 1597c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1598c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1599c8587f34SStefano Zampini { 16008629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1601c8587f34SStefano Zampini PetscErrorCode ierr; 1602c8587f34SStefano Zampini 1603c8587f34SStefano Zampini PetscFunctionBegin; 1604f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 16055e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1606c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1607c8587f34SStefano Zampini 1608684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 16090fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1610684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1611c8587f34SStefano Zampini 16128629588bSStefano Zampini /* 16138629588bSStefano Zampini Setup local correction and local part of coarse basis. 16148629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 16158629588bSStefano Zampini */ 161647f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 16178629588bSStefano Zampini 16188629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 16198629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 16208629588bSStefano Zampini 16218629588bSStefano Zampini /* free */ 16228629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1623c8587f34SStefano Zampini PetscFunctionReturn(0); 1624c8587f34SStefano Zampini } 1625c8587f34SStefano Zampini 1626c8587f34SStefano Zampini #undef __FUNCT__ 1627674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1628674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1629674ae819SStefano Zampini { 1630674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1631674ae819SStefano Zampini PetscErrorCode ierr; 1632674ae819SStefano Zampini 1633674ae819SStefano Zampini PetscFunctionBegin; 1634674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1635674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 163630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1637674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1638785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1639674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1640f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1641f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1642785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 164363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 164463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1645674ae819SStefano Zampini PetscFunctionReturn(0); 1646674ae819SStefano Zampini } 1647674ae819SStefano Zampini 1648674ae819SStefano Zampini #undef __FUNCT__ 1649674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1650674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1651674ae819SStefano Zampini { 1652674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16534f1b2e48SStefano Zampini PetscInt i; 1654674ae819SStefano Zampini PetscErrorCode ierr; 1655674ae819SStefano Zampini 1656674ae819SStefano Zampini PetscFunctionBegin; 1657b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1658674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 165916909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 16601dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 1661674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1662669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 1663fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 1664674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 16654f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 16664f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 16674f1b2e48SStefano Zampini } 16684f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1669b334f244SStefano Zampini if (pcbddc->sub_schurs) { 1670b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1671b334f244SStefano Zampini } 1672674ae819SStefano Zampini PetscFunctionReturn(0); 1673674ae819SStefano Zampini } 1674674ae819SStefano Zampini 1675674ae819SStefano Zampini #undef __FUNCT__ 1676674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1677674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1678674ae819SStefano Zampini { 1679674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1680674ae819SStefano Zampini PetscErrorCode ierr; 1681674ae819SStefano Zampini 1682674ae819SStefano Zampini PetscFunctionBegin; 1683674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 168458da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1685ca92afb2SStefano Zampini PetscScalar *array; 168606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 168706656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 168858da7f69SStefano Zampini } 1689674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1690674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 169115aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 169215aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1693674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1694674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1695674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 169606656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1697674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1698674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 16998ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1700674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1701674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1702674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1703f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1704f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1705f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1706f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1707727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 17080e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1709f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 171070cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 171181d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 17120369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 17131dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 17144f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 17158b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1716ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1717ca92afb2SStefano Zampini PetscInt i; 1718ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1719ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1720ca92afb2SStefano Zampini } 1721ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1722ca92afb2SStefano Zampini } 17234f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1724674ae819SStefano Zampini PetscFunctionReturn(0); 1725674ae819SStefano Zampini } 1726674ae819SStefano Zampini 1727674ae819SStefano Zampini #undef __FUNCT__ 1728f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1729f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 17306bfb1811SStefano Zampini { 17316bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 17326bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 17336bfb1811SStefano Zampini VecType impVecType; 17344f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 17356bfb1811SStefano Zampini PetscErrorCode ierr; 17366bfb1811SStefano Zampini 17376bfb1811SStefano Zampini PetscFunctionBegin; 17386c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1739e7b262bdSStefano Zampini /* get sizes */ 17404f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1741b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 17426bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1743e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1744e7b262bdSStefano Zampini /* R nodes */ 1745e7b262bdSStefano Zampini old_size = -1; 1746e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1747e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1748e7b262bdSStefano Zampini } 1749e7b262bdSStefano Zampini if (n_R != old_size) { 1750e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1751e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 17526bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 17536bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 17546bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 17556bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1756e7b262bdSStefano Zampini } 1757e7b262bdSStefano Zampini /* local primal dofs */ 1758e7b262bdSStefano Zampini old_size = -1; 1759e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1760e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1761e7b262bdSStefano Zampini } 1762e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1763e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 176483b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1765e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 17666bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1767e7b262bdSStefano Zampini } 1768e7b262bdSStefano Zampini /* local explicit constraints */ 1769e7b262bdSStefano Zampini old_size = -1; 1770e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1771e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1772e7b262bdSStefano Zampini } 1773e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1774e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 177583b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 177683b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 177783b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 177883b7ccabSStefano Zampini } 17796bfb1811SStefano Zampini PetscFunctionReturn(0); 17806bfb1811SStefano Zampini } 17816bfb1811SStefano Zampini 17826bfb1811SStefano Zampini #undef __FUNCT__ 178347f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 178447f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 178588ebb749SStefano Zampini { 178625084f0cSStefano Zampini PetscErrorCode ierr; 178725084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 178888ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 178988ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1790d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 179125084f0cSStefano Zampini /* submatrices of local problem */ 179280677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 179306656605SStefano Zampini /* submatrices of local coarse problem */ 179406656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 179525084f0cSStefano Zampini /* working matrices */ 179606656605SStefano Zampini Mat C_CR; 179725084f0cSStefano Zampini /* additional working stuff */ 179806656605SStefano Zampini PC pc_R; 17994f1b2e48SStefano Zampini Mat F; 18005cbda25cSStefano Zampini Vec dummy_vec; 1801a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 180225084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 180306656605SStefano Zampini PetscScalar *work; 180406656605SStefano Zampini PetscInt *idx_V_B; 1805ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 180606656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1807ffd830a3SStefano Zampini 180825084f0cSStefano Zampini /* some shortcuts to scalars */ 180906656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 181088ebb749SStefano Zampini 181188ebb749SStefano Zampini PetscFunctionBegin; 1812*9a962809SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1813ffd830a3SStefano Zampini 1814ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1815b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 18164f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1817b371cd4fSStefano Zampini n_B = pcis->n_B; 1818b371cd4fSStefano Zampini n_D = pcis->n - n_B; 181988ebb749SStefano Zampini n_R = pcis->n - n_vertices; 182088ebb749SStefano Zampini 182188ebb749SStefano Zampini /* vertices in boundary numbering */ 1822785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 18230e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 18246c4ed002SBarry 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); 182588ebb749SStefano Zampini 182606656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1827019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 182806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 182906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 183006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 183106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 183206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 183306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 183406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 183506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 183606656605SStefano Zampini 183706656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 183806656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 183906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 184006656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 184106656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1842ffd830a3SStefano Zampini lda_rhs = n_R; 1843a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 184406656605SStefano Zampini if (isLU || isILU || isCHOL) { 184506656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1846b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 1847df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1848d62866d3SStefano Zampini MatFactorType type; 1849d62866d3SStefano Zampini 1850df4d28bfSStefano Zampini F = reuse_solver->F; 18516816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1852d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1853ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 185422db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 185506656605SStefano Zampini } else { 185606656605SStefano Zampini F = NULL; 185706656605SStefano Zampini } 185806656605SStefano Zampini 1859ffd830a3SStefano Zampini /* allocate workspace */ 1860ffd830a3SStefano Zampini n = 0; 1861ffd830a3SStefano Zampini if (n_constraints) { 1862ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1863ffd830a3SStefano Zampini } 1864ffd830a3SStefano Zampini if (n_vertices) { 1865ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1866ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1867ffd830a3SStefano Zampini } 1868ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1869ffd830a3SStefano Zampini 18705cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 18715cbda25cSStefano Zampini dummy_vec = NULL; 18725cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 18735cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 18745cbda25cSStefano Zampini } 18755cbda25cSStefano Zampini 187688ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 187788ebb749SStefano Zampini if (n_constraints) { 187872b8c272SStefano Zampini Mat M1,M2,M3,C_B; 187906656605SStefano Zampini IS is_aux; 188080677318SStefano Zampini PetscScalar *array,*array2; 188106656605SStefano Zampini 1882f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 188380677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 188488ebb749SStefano Zampini 188525084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 188625084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 18878ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 188872b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 188988ebb749SStefano Zampini 189080677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 189180677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1892ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 189388ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 189406656605SStefano Zampini const PetscScalar *row_cmat_values; 189506656605SStefano Zampini const PetscInt *row_cmat_indices; 189606656605SStefano Zampini PetscInt size_of_constraint,j; 189788ebb749SStefano Zampini 189806656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 189906656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1900ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 190106656605SStefano Zampini } 190206656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 190306656605SStefano Zampini } 1904ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 190506656605SStefano Zampini if (F) { 190606656605SStefano Zampini Mat B; 190706656605SStefano Zampini 1908ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1909a3df083aSStefano Zampini if (need_benign_correction) { 1910df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1911a3df083aSStefano Zampini 191272b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 191372b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 1914a3df083aSStefano Zampini } 191580677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1916a3df083aSStefano Zampini if (need_benign_correction) { 1917a3df083aSStefano Zampini PetscScalar *marr; 1918df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1919a3df083aSStefano Zampini 1920a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 19215cbda25cSStefano Zampini if (lda_rhs != n_R) { 19225cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 19235cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 19245cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 19255cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 19265cbda25cSStefano Zampini } 19275cbda25cSStefano Zampini } else { 1928a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1929a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 19305cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 1931a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1932a3df083aSStefano Zampini } 19335cbda25cSStefano Zampini } 1934a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1935a3df083aSStefano Zampini } 193606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 193706656605SStefano Zampini } else { 193880677318SStefano Zampini PetscScalar *marr; 193980677318SStefano Zampini 194080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 194106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1942ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1943ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 194406656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 194506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 194606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 194706656605SStefano Zampini } 194880677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 194906656605SStefano Zampini } 195080677318SStefano Zampini if (!pcbddc->switch_static) { 195180677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 195280677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 195380677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 195480677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1955ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 195680677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 195780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195980677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 196080677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 196180677318SStefano Zampini } 196280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 196380677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 196472b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 196580677318SStefano Zampini } else { 1966ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1967ffd830a3SStefano Zampini IS dummy; 1968ffd830a3SStefano Zampini 1969ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 197072b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1971ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1972ffd830a3SStefano Zampini } else { 197380677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 197480677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1975ffd830a3SStefano Zampini } 197625084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 197780677318SStefano Zampini } 197880677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 197980677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 198080677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 198106656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 198206656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 198380677318SStefano Zampini if (isCHOL) { 198480677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 198580677318SStefano Zampini } else { 198625084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 198780677318SStefano Zampini } 198880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 198906656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 199025084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 199125084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 199225084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 199380677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 199472b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 199572b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 199606656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 199706656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1998f4ddd8eeSStefano Zampini } 1999fc227af8SStefano Zampini 2000fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 200188ebb749SStefano Zampini if (n_vertices) { 200206656605SStefano Zampini IS is_aux; 20033a50541eSStefano Zampini 2004b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 20056816873aSStefano Zampini IS tis; 20066816873aSStefano Zampini 20076816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 20086816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 20096816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 20106816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 20116816873aSStefano Zampini } else { 20123a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 20136816873aSStefano Zampini } 20149577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 20159577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 201604708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 201725084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 201888ebb749SStefano Zampini } 201988ebb749SStefano Zampini 202088ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 2021f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 202206656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 202306656605SStefano Zampini if (pcbddc->coarse_phi_D) { 202406656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 202506656605SStefano Zampini } 2026f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 202706656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 202806656605SStefano Zampini PetscScalar *marray; 202906656605SStefano Zampini 203006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 203106656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 2032f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2033f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 2034f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 2035f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2036f4ddd8eeSStefano Zampini } 2037f4ddd8eeSStefano Zampini } 203806656605SStefano Zampini 2039f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 204006656605SStefano Zampini PetscScalar *marray; 204188ebb749SStefano Zampini 204206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 20438eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 204406656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 204588ebb749SStefano Zampini } 20463301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 204706656605SStefano Zampini n *= 2; 204888ebb749SStefano Zampini } 204906656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 205006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 205106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 20528eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 205306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 205406656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 205588ebb749SStefano Zampini } 20563301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 205706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 20588eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 205906656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 206006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 206188ebb749SStefano Zampini } 206288ebb749SStefano Zampini } else { 2063c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 2064c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 20651b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2066c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 2067c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 2068c0553b1fSStefano Zampini } 206988ebb749SStefano Zampini } 207006656605SStefano Zampini } 2071019a44ceSStefano Zampini 207206656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 20734f1b2e48SStefano Zampini p0_lidx_I = NULL; 20744f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 2075d12edf2fSStefano Zampini const PetscInt *idxs; 2076d12edf2fSStefano Zampini 2077d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 20784f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 20794f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20804f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 20814f1b2e48SStefano Zampini } 2082d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 2083d12edf2fSStefano Zampini } 2084d16cbb6bSStefano Zampini 208506656605SStefano Zampini /* vertices */ 208606656605SStefano Zampini if (n_vertices) { 208716f15bc4SStefano Zampini 2088af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 208904708bb6SStefano Zampini 209016f15bc4SStefano Zampini if (n_R) { 209114393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 209206656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 209316f15bc4SStefano Zampini PetscScalar *x,*y; 209404708bb6SStefano Zampini PetscBool isseqaij; 209506656605SStefano Zampini 209621eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 209714393ed6SStefano Zampini if (need_benign_correction) { 209814393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 209914393ed6SStefano Zampini IS is_p0; 210014393ed6SStefano Zampini PetscInt *idxs_p0,n; 210114393ed6SStefano Zampini 210214393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 210314393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 210414393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 2105af25d912SStefano 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); 210614393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 210714393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 210814393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 210914393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 211014393ed6SStefano Zampini } 211114393ed6SStefano Zampini 2112ffd830a3SStefano Zampini if (lda_rhs == n_R) { 2113af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2114ffd830a3SStefano Zampini } else { 2115ca92afb2SStefano Zampini PetscScalar *av,*array; 2116ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 2117ca92afb2SStefano Zampini PetscInt n; 2118ca92afb2SStefano Zampini PetscBool flg_row; 2119ffd830a3SStefano Zampini 2120ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 2121ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 21229d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2123ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2124ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 2125ca92afb2SStefano Zampini for (i=0;i<n;i++) { 2126ca92afb2SStefano Zampini PetscInt j; 2127ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 2128ffd830a3SStefano Zampini } 2129ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2130ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2131ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 2132ffd830a3SStefano Zampini } 2133ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2134a3df083aSStefano Zampini if (need_benign_correction) { 2135df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2136a3df083aSStefano Zampini PetscScalar *marr; 2137a3df083aSStefano Zampini 2138a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 213914393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 214014393ed6SStefano Zampini 214114393ed6SStefano Zampini | 0 0 0 | (V) 214214393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 214314393ed6SStefano Zampini | 0 0 -1 | (p0) 214414393ed6SStefano Zampini 214514393ed6SStefano Zampini */ 2146df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 214714393ed6SStefano Zampini const PetscScalar *vals; 214814393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 214914393ed6SStefano Zampini PetscInt n,j,nz; 215014393ed6SStefano Zampini 2151df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2152df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 215314393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 215414393ed6SStefano Zampini for (j=0;j<n;j++) { 215514393ed6SStefano Zampini PetscScalar val = vals[j]; 215614393ed6SStefano Zampini PetscInt k,col = idxs[j]; 215714393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 215814393ed6SStefano Zampini } 215914393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2160df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 216114393ed6SStefano Zampini } 216272b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 216372b8c272SStefano Zampini } 216472b8c272SStefano Zampini if (F) { 216514393ed6SStefano Zampini /* need to correct the rhs */ 216672b8c272SStefano Zampini if (need_benign_correction) { 216772b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 216872b8c272SStefano Zampini PetscScalar *marr; 216972b8c272SStefano Zampini 217072b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 21715cbda25cSStefano Zampini if (lda_rhs != n_R) { 21725cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 21735cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 21745cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 21755cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 21765cbda25cSStefano Zampini } 21775cbda25cSStefano Zampini } else { 2178a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2179a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 21805cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2181a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2182a3df083aSStefano Zampini } 21835cbda25cSStefano Zampini } 2184a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 2185a3df083aSStefano Zampini } 218606656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 218714393ed6SStefano Zampini /* need to correct the solution */ 2188a3df083aSStefano Zampini if (need_benign_correction) { 2189df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2190a3df083aSStefano Zampini PetscScalar *marr; 2191a3df083aSStefano Zampini 2192a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 21935cbda25cSStefano Zampini if (lda_rhs != n_R) { 21945cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 21955cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 21965cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 21975cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 21985cbda25cSStefano Zampini } 21995cbda25cSStefano Zampini } else { 2200a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2201a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 22025cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2203a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2204a3df083aSStefano Zampini } 22055cbda25cSStefano Zampini } 2206a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 2207a3df083aSStefano Zampini } 220806656605SStefano Zampini } else { 220906656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 221006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 2211ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 2212ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 221306656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 221406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 221506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 221606656605SStefano Zampini } 221706656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 221806656605SStefano Zampini } 221980677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2220ffd830a3SStefano Zampini /* S_VV and S_CV */ 222106656605SStefano Zampini if (n_constraints) { 222206656605SStefano Zampini Mat B; 222380677318SStefano Zampini 2224ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 222580677318SStefano Zampini for (i=0;i<n_vertices;i++) { 2226ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 2227ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 222880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 222980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 223080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 223180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 223280677318SStefano Zampini } 2233ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 223480677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 223580677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 2236ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 223780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 223806656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 2239ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 2240ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 224106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 224206656605SStefano Zampini } 224304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 224404708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 2245511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 224604708bb6SStefano Zampini } 2247ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2248ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 2249ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2250ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 2251ffd830a3SStefano Zampini } 225206656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 225314393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 225414393ed6SStefano Zampini if (need_benign_correction) { 2255df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 225614393ed6SStefano Zampini PetscScalar *marr,*sums; 225714393ed6SStefano Zampini 225814393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 225914393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 2260df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 226114393ed6SStefano Zampini const PetscScalar *vals; 226214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 226314393ed6SStefano Zampini PetscInt n,j,nz; 226414393ed6SStefano Zampini 2265df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2266df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 226714393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 226814393ed6SStefano Zampini PetscInt k; 226914393ed6SStefano Zampini sums[j] = 0.; 227014393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 227114393ed6SStefano Zampini } 227214393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 227314393ed6SStefano Zampini for (j=0;j<n;j++) { 227414393ed6SStefano Zampini PetscScalar val = vals[j]; 227514393ed6SStefano Zampini PetscInt k; 227614393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 227714393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 227814393ed6SStefano Zampini } 227914393ed6SStefano Zampini } 228014393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2281df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 228214393ed6SStefano Zampini } 228314393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 228414393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 228514393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 228614393ed6SStefano Zampini } 228780677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 228806656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 228906656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 229006656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 229106656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 229206656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 229306656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 229406656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2295d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 2296019a44ceSStefano Zampini } else { 2297d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2298d16cbb6bSStefano Zampini } 229921eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 2300d16cbb6bSStefano Zampini 230106656605SStefano Zampini /* coarse basis functions */ 230206656605SStefano Zampini for (i=0;i<n_vertices;i++) { 230316f15bc4SStefano Zampini PetscScalar *y; 230416f15bc4SStefano Zampini 2305ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 230606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 230706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 230806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 230906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 231006656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 231106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 231206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 231306656605SStefano Zampini 231406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 23154f1b2e48SStefano Zampini PetscInt j; 23164f1b2e48SStefano Zampini 231706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 231806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 231906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 23224f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 232306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 232406656605SStefano Zampini } 232506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 232606656605SStefano Zampini } 232704708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 232804708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 232906656605SStefano Zampini } 23305cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 233106656605SStefano Zampini 233206656605SStefano Zampini if (n_constraints) { 233306656605SStefano Zampini Mat B; 233406656605SStefano Zampini 2335ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 233606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 233780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 233806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 233906656605SStefano Zampini if (n_vertices) { 234080677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 234180677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 234280677318SStefano Zampini } else { 234380677318SStefano Zampini Mat S_VCt; 234480677318SStefano Zampini 2345ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2346ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 234772b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 2348ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 2349ffd830a3SStefano Zampini } 235080677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 235180677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 235280677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 235380677318SStefano Zampini } 235406656605SStefano Zampini } 235506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 235606656605SStefano Zampini /* coarse basis functions */ 235706656605SStefano Zampini for (i=0;i<n_constraints;i++) { 235806656605SStefano Zampini PetscScalar *y; 235906656605SStefano Zampini 2360ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 236106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 236206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 236306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 236406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 236506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 236606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 236706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 23684f1b2e48SStefano Zampini PetscInt j; 23694f1b2e48SStefano Zampini 237006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 237106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 237206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 237306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 237406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 23754f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 237606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 237706656605SStefano Zampini } 237806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 237906656605SStefano Zampini } 238006656605SStefano Zampini } 238180677318SStefano Zampini if (n_constraints) { 238280677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 238380677318SStefano Zampini } 23844f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 238572b8c272SStefano Zampini 238672b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 238772b8c272SStefano Zampini if (pcbddc->benign_n) { 238872b8c272SStefano Zampini Mat B0_B,B0_BPHI; 238972b8c272SStefano Zampini IS is_dummy; 239072b8c272SStefano Zampini PetscScalar *data; 239172b8c272SStefano Zampini PetscInt j; 239272b8c272SStefano Zampini 239372b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 239472b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 239572b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 239672b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 239786c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 239872b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 239972b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 240072b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 240172b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 240272b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 240372b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 240472b8c272SStefano Zampini } 240572b8c272SStefano Zampini } 240672b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 240772b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 240872b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 240972b8c272SStefano Zampini } 2410019a44ceSStefano Zampini 241106656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 24123301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 2413ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 2414ffd830a3SStefano Zampini PetscScalar *marray; 241506656605SStefano Zampini 241606656605SStefano Zampini if (n_constraints) { 2417ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 241806656605SStefano Zampini 2419af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 242006656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 2421ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 242216f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 242306656605SStefano Zampini if (n_vertices) { 2424ffd830a3SStefano Zampini Mat S_VCT; 242506656605SStefano Zampini 242606656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 2427ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 242816f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 242906656605SStefano Zampini } 2430ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 24315b782168SStefano Zampini } else { 24325b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 243306656605SStefano Zampini } 243416f15bc4SStefano Zampini if (n_vertices && n_R) { 2435ffd830a3SStefano Zampini PetscScalar *av,*marray; 2436ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 2437ffd830a3SStefano Zampini PetscInt n; 2438ffd830a3SStefano Zampini PetscBool flg_row; 243906656605SStefano Zampini 2440ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 2441af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 2442ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2443ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 2444ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2445ffd830a3SStefano Zampini for (i=0;i<n;i++) { 2446ffd830a3SStefano Zampini PetscInt j; 2447ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 2448ffd830a3SStefano Zampini } 2449ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2450ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2451ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 245206656605SStefano Zampini } 245306656605SStefano Zampini 2454ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 2455ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2456ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 2457ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 2458ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 245906656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 246006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 246106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 246206656605SStefano Zampini } 2463ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 24645b782168SStefano Zampini if (B_C) { 2465ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 2466ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 2467ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 2468ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 2469ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2470ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2471ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 247206656605SStefano Zampini } 2473ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 24745b782168SStefano Zampini } 247506656605SStefano Zampini /* coarse basis functions */ 247606656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 247706656605SStefano Zampini PetscScalar *y; 247806656605SStefano Zampini 2479ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 248006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 248106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 248206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248406656605SStefano Zampini if (i<n_vertices) { 248506656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 248606656605SStefano Zampini } 248706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 248806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 248906656605SStefano Zampini 249006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 249106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 249206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 249306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 249606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 249706656605SStefano Zampini } 249806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 249906656605SStefano Zampini } 2500ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2501ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 250206656605SStefano Zampini } 2503d62866d3SStefano Zampini /* free memory */ 250488ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 250506656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 250606656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 250706656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 250806656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2509d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2510d62866d3SStefano Zampini if (n_vertices) { 2511d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2512d62866d3SStefano Zampini } 2513d62866d3SStefano Zampini if (n_constraints) { 2514d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2515d62866d3SStefano Zampini } 251688ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 251788ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 251888ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2519d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 252088ebb749SStefano Zampini Mat coarse_sub_mat; 252125084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 252288ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 252388ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 252488ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 25258bec7fa6SStefano Zampini Mat C_B,CPHI; 25268bec7fa6SStefano Zampini IS is_dummy; 25278bec7fa6SStefano Zampini Vec mones; 252888ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 252988ebb749SStefano Zampini PetscReal real_value; 253088ebb749SStefano Zampini 2531a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2532a3df083aSStefano Zampini Mat A; 2533a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2534a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2535a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2536a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2537a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2538a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2539a3df083aSStefano Zampini } else { 254088ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 254188ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 254288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 254388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2544a3df083aSStefano Zampini } 254588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 254688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2547ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 254888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 254988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 255088ebb749SStefano Zampini } 255188ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 255288ebb749SStefano Zampini 255325084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 25543301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 255525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2556ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 255788ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 255888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 255988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 256088ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 256188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 256288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 256388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 256488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 256588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 256688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 256788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 256888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 256988ebb749SStefano Zampini } else { 257088ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 257188ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 257288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 257388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 257488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 257588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 257688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 257788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 257888ebb749SStefano Zampini } 257988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 258088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 258188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2582511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 25834f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2584fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 2585d12edf2fSStefano Zampini PetscScalar *data,*data2; 25864f1b2e48SStefano Zampini PetscInt j; 2587d12edf2fSStefano Zampini 25884f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2589fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 2590d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 259186c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2592d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2593d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 25944f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 25954f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2596d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 25974f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 25984f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 25994f1b2e48SStefano Zampini } 2600d12edf2fSStefano Zampini } 2601d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2602d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2603d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2604d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2605d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2606d12edf2fSStefano Zampini } 2607d12edf2fSStefano Zampini #if 0 2608d12edf2fSStefano Zampini { 2609d12edf2fSStefano Zampini PetscViewer viewer; 2610d12edf2fSStefano Zampini char filename[256]; 2611ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2612d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2613d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2614ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2615ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2616ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2617d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 261872b8c272SStefano Zampini if (save_change) { 261972b8c272SStefano Zampini Mat phi_B; 262072b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 262172b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 262272b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 262372b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 262472b8c272SStefano Zampini } else { 2625ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2626ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 262772b8c272SStefano Zampini } 2628ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2629ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2630ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2631ffd830a3SStefano Zampini } 2632ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2633ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2634ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2635ffd830a3SStefano Zampini } 263672b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 2637ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2638ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2639ffd830a3SStefano Zampini } 2640d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2641d12edf2fSStefano Zampini } 2642d12edf2fSStefano Zampini #endif 264381d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 26448bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 26451575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 264606656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 26478bec7fa6SStefano Zampini 26488bec7fa6SStefano Zampini /* check constraints */ 2649a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2650a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 26514f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 26528bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2653a00504b5SStefano Zampini } else { 2654a00504b5SStefano Zampini PetscScalar *data; 2655a00504b5SStefano Zampini Mat tmat; 2656a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2657a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 2658a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2659a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2660a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2661a00504b5SStefano Zampini } 26628bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 26638bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 26648bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 26658bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2666bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2667ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2668bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2669bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2670bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2671bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2672bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 267388ebb749SStefano Zampini } 26748bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 26758bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 26768bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 26778bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 267825084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 267988ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 268088ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 268188ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 268288ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 268388ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 268488ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 268588ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 268688ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 268788ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 268888ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2689ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 269088ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 269188ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 269288ebb749SStefano Zampini } 269388ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 269488ebb749SStefano Zampini } 26958629588bSStefano Zampini /* get back data */ 26968629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 269788ebb749SStefano Zampini PetscFunctionReturn(0); 269888ebb749SStefano Zampini } 269988ebb749SStefano Zampini 270088ebb749SStefano Zampini #undef __FUNCT__ 2701d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2702d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2703aa0d41d4SStefano Zampini { 2704d65f70fdSStefano Zampini Mat *work_mat; 2705d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2706d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2707c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 2708aa0d41d4SStefano Zampini PetscErrorCode ierr; 2709aa0d41d4SStefano Zampini 2710aa0d41d4SStefano Zampini PetscFunctionBegin; 2711d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2712d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2713d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2714d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2715aa0d41d4SStefano Zampini 2716d65f70fdSStefano Zampini if (!rsorted) { 2717906d46d4SStefano Zampini const PetscInt *idxs; 2718906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2719aa0d41d4SStefano Zampini 2720d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2721d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2722d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2723d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2724aa0d41d4SStefano Zampini } 2725d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2726d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2727d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2728d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2729aa0d41d4SStefano Zampini } 2730d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2731d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2732d65f70fdSStefano Zampini } else { 2733d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2734d65f70fdSStefano Zampini isrow_s = isrow; 2735aa0d41d4SStefano Zampini } 2736906d46d4SStefano Zampini 2737d65f70fdSStefano Zampini if (!csorted) { 2738d65f70fdSStefano Zampini if (isrow == iscol) { 2739d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2740d65f70fdSStefano Zampini iscol_s = isrow_s; 2741d65f70fdSStefano Zampini } else { 2742d65f70fdSStefano Zampini const PetscInt *idxs; 2743d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2744906d46d4SStefano Zampini 2745d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2746d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2747d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2748d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2749d65f70fdSStefano Zampini } 2750d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2751d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2752d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2753d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2754d65f70fdSStefano Zampini } 2755d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2756d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2757d65f70fdSStefano Zampini } 2758d65f70fdSStefano Zampini } else { 2759d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2760d65f70fdSStefano Zampini iscol_s = iscol; 2761d65f70fdSStefano Zampini } 2762d65f70fdSStefano Zampini 2763d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2764d65f70fdSStefano Zampini 2765d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2766906d46d4SStefano Zampini Mat new_mat; 2767d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2768906d46d4SStefano Zampini 2769d65f70fdSStefano Zampini if (!rsorted) { 2770d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2771d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2772d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2773d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2774906d46d4SStefano Zampini } 2775d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2776d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2777d65f70fdSStefano Zampini } else { 2778d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2779906d46d4SStefano Zampini } 2780d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2781d65f70fdSStefano Zampini 2782d65f70fdSStefano Zampini if (!csorted) { 2783d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2784d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2785d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2786d65f70fdSStefano Zampini } else { 2787d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2788d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2789d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2790d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2791d65f70fdSStefano Zampini } 2792d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2793d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2794d65f70fdSStefano Zampini } 2795d65f70fdSStefano Zampini } else { 2796d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2797d65f70fdSStefano Zampini } 2798d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2799d65f70fdSStefano Zampini 2800d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2801d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2802d65f70fdSStefano Zampini work_mat[0] = new_mat; 2803d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2804d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2805d65f70fdSStefano Zampini } 2806d65f70fdSStefano Zampini 2807d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2808d65f70fdSStefano Zampini *B = work_mat[0]; 2809d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2810d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2811d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2812d65f70fdSStefano Zampini PetscFunctionReturn(0); 2813d65f70fdSStefano Zampini } 2814d65f70fdSStefano Zampini 2815d65f70fdSStefano Zampini #undef __FUNCT__ 28165e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 28175e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2818aa0d41d4SStefano Zampini { 2819aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 28205e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2821d65f70fdSStefano Zampini Mat new_mat; 28225e8657edSStefano Zampini IS is_local,is_global; 2823d65f70fdSStefano Zampini PetscInt local_size; 2824d65f70fdSStefano Zampini PetscBool isseqaij; 2825aa0d41d4SStefano Zampini PetscErrorCode ierr; 2826aa0d41d4SStefano Zampini 2827aa0d41d4SStefano Zampini PetscFunctionBegin; 2828aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 28295e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 28305e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2831b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2832aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2833d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2834aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2835906d46d4SStefano Zampini 2836906d46d4SStefano Zampini /* check */ 2837906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2838906d46d4SStefano Zampini Vec x,x_change; 2839906d46d4SStefano Zampini PetscReal error; 2840906d46d4SStefano Zampini 28415e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2842906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 28435e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2844e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2845e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2846d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2847e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2848e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2849906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2850906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2851906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2852906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2853906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2854906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2855906d46d4SStefano Zampini } 2856906d46d4SStefano Zampini 285722d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 28589b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 285922d5777bSStefano Zampini if (isseqaij) { 2860a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2861a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 2862aa0d41d4SStefano Zampini } else { 2863a00504b5SStefano Zampini Mat work_mat; 28641cf9b237SStefano Zampini 2865a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2866aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2867a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 28681d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2869aa0d41d4SStefano Zampini } 28703301b35fSStefano Zampini if (matis->A->symmetric_set) { 28713301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2872e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 28733301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2874e496cd5dSStefano Zampini #endif 28753301b35fSStefano Zampini } 2876d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2877aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2878aa0d41d4SStefano Zampini } 2879aa0d41d4SStefano Zampini 2880aa0d41d4SStefano Zampini #undef __FUNCT__ 2881a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 28828ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2883a64d13efSStefano Zampini { 2884a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2885a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2886d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 288753892102SStefano Zampini PetscInt *idx_R_local=NULL; 28883a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 28893a50541eSStefano Zampini PetscInt vbs,bs; 28906816873aSStefano Zampini PetscBT bitmask=NULL; 2891a64d13efSStefano Zampini PetscErrorCode ierr; 2892a64d13efSStefano Zampini 2893a64d13efSStefano Zampini PetscFunctionBegin; 2894b23d619eSStefano Zampini /* 2895b23d619eSStefano Zampini No need to setup local scatters if 2896b23d619eSStefano Zampini - primal space is unchanged 2897b23d619eSStefano Zampini AND 2898b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2899b23d619eSStefano Zampini AND 2900b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2901b23d619eSStefano Zampini */ 2902b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2903f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2904f4ddd8eeSStefano Zampini } 2905f4ddd8eeSStefano Zampini /* destroy old objects */ 2906f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2907f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2908f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2909a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2910b371cd4fSStefano Zampini n_B = pcis->n_B; 2911b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2912b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 29133a50541eSStefano Zampini 2914a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 29156816873aSStefano Zampini 291653892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 2917b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 2918854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2919a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2920a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 29210e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2922a64d13efSStefano Zampini } 2923a64d13efSStefano Zampini 2924a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 29254641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 29266816873aSStefano Zampini idx_R_local[n_R++] = i; 2927a64d13efSStefano Zampini } 2928a64d13efSStefano Zampini } 2929df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 2930df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 29316816873aSStefano Zampini 2932df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2933df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 29346816873aSStefano Zampini } 29353a50541eSStefano Zampini 29363a50541eSStefano Zampini /* Block code */ 29373a50541eSStefano Zampini vbs = 1; 29383a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 29393a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 29403a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 29413a50541eSStefano Zampini PetscInt *vary; 2942b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 2943785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 29443a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2945d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2946d3df7717SStefano 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 */ 29470e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2948d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 29493a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 29503a50541eSStefano Zampini is_blocked = PETSC_FALSE; 29513a50541eSStefano Zampini break; 29523a50541eSStefano Zampini } 29533a50541eSStefano Zampini } 2954d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2955d3df7717SStefano Zampini } else { 2956d3df7717SStefano Zampini /* Verify directly the R set */ 2957d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2958d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2959d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2960d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2961d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2962d3df7717SStefano Zampini break; 2963d3df7717SStefano Zampini } 2964d3df7717SStefano Zampini } 2965d3df7717SStefano Zampini } 2966d3df7717SStefano Zampini } 29673a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 29683a50541eSStefano Zampini vbs = bs; 29693a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 29703a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 29713a50541eSStefano Zampini } 29723a50541eSStefano Zampini } 29733a50541eSStefano Zampini } 29743a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 2975b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 2976df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 297753892102SStefano Zampini 2978df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2979df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 298053892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 2981df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 298253892102SStefano Zampini } else { 29833a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 298453892102SStefano Zampini } 2985a64d13efSStefano Zampini 2986a64d13efSStefano Zampini /* print some info if requested */ 2987a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2988a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2989a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 29901575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2991a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2992a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 29934f1b2e48SStefano 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); 2994a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2995a64d13efSStefano Zampini } 2996a64d13efSStefano Zampini 2997a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 2998b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 29996816873aSStefano Zampini IS is_aux1,is_aux2; 30006816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 30016816873aSStefano Zampini 30023a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3003854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 3004854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 3005a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 30064641a718SStefano Zampini for (i=0; i<n_D; i++) { 30074641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 30084641a718SStefano Zampini } 3009a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3010a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 30114641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 30124641a718SStefano Zampini aux_array1[j++] = i; 3013a64d13efSStefano Zampini } 3014a64d13efSStefano Zampini } 3015a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3016a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3017a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 30184641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 30194641a718SStefano Zampini aux_array2[j++] = i; 3020a64d13efSStefano Zampini } 3021a64d13efSStefano Zampini } 3022a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3023a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 3024a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 3025a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3026a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 3027a64d13efSStefano Zampini 30288eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3029785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 3030a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 30314641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 30324641a718SStefano Zampini aux_array1[j++] = i; 3033a64d13efSStefano Zampini } 3034a64d13efSStefano Zampini } 3035a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3036a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 3037a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3038a64d13efSStefano Zampini } 30394641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 30403a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3041d62866d3SStefano Zampini } else { 3042df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 30436816873aSStefano Zampini IS tis; 30446816873aSStefano Zampini PetscInt schur_size; 30456816873aSStefano Zampini 3046df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 30476816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 3048df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 30496816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 30506816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 30516816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 30526816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 30536816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 3054d62866d3SStefano Zampini } 3055d62866d3SStefano Zampini } 3056a64d13efSStefano Zampini PetscFunctionReturn(0); 3057a64d13efSStefano Zampini } 3058a64d13efSStefano Zampini 3059304d26faSStefano Zampini 3060304d26faSStefano Zampini #undef __FUNCT__ 3061304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 3062684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 3063304d26faSStefano Zampini { 3064304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3065304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3066304d26faSStefano Zampini PC pc_temp; 3067304d26faSStefano Zampini Mat A_RR; 3068f4ddd8eeSStefano Zampini MatReuse reuse; 3069304d26faSStefano Zampini PetscScalar m_one = -1.0; 3070304d26faSStefano Zampini PetscReal value; 307104708bb6SStefano Zampini PetscInt n_D,n_R; 3072c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 3073304d26faSStefano Zampini PetscErrorCode ierr; 3074e604994aSStefano Zampini /* prefixes stuff */ 3075312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 3076e604994aSStefano Zampini size_t len; 3077304d26faSStefano Zampini 3078304d26faSStefano Zampini PetscFunctionBegin; 3079304d26faSStefano Zampini 3080e604994aSStefano Zampini /* compute prefixes */ 3081e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 3082e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 3083e604994aSStefano Zampini if (!pcbddc->current_level) { 3084e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3085e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3086e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3087e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3088e604994aSStefano Zampini } else { 3089e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 3090312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 3091e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 3092e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 3093312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 3094312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 309534d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 309634d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 3097e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3098e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3099e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 3100e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 3101e604994aSStefano Zampini } 3102e604994aSStefano Zampini 3103304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 3104684f6988SStefano Zampini if (dirichlet) { 3105d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3106450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3107*9a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 3108450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 3109a3df083aSStefano Zampini Mat A_IIn; 3110a3df083aSStefano Zampini 3111a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 3112a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 3113a3df083aSStefano Zampini pcis->A_II = A_IIn; 3114a3df083aSStefano Zampini } 3115450f8f5eSStefano Zampini } 31163301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 31173301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 3118964fefecSStefano Zampini } 3119ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 3120964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 3121304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 3122304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 3123304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 3124304d26faSStefano Zampini /* default */ 3125304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 3126e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 31279577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 3128304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 31299577ea80SStefano Zampini if (issbaij) { 31309577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 31319577ea80SStefano Zampini } else { 3132304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 31339577ea80SStefano Zampini } 3134304d26faSStefano Zampini /* Allow user's customization */ 3135304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 3136304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3137304d26faSStefano Zampini } 3138d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 3139b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3140df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3141d62866d3SStefano Zampini 3142df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 3143d5574798SStefano Zampini } 3144304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3145304d26faSStefano Zampini if (!n_D) { 3146304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 3147304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3148304d26faSStefano Zampini } 3149304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 3150304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 3151304d26faSStefano Zampini /* set ksp_D into pcis data */ 3152304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 3153304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 3154304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 3155684f6988SStefano Zampini } 3156304d26faSStefano Zampini 3157304d26faSStefano Zampini /* NEUMANN PROBLEM */ 3158684f6988SStefano Zampini A_RR = 0; 3159684f6988SStefano Zampini if (neumann) { 3160d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 316104708bb6SStefano Zampini PetscInt ibs,mbs; 316204708bb6SStefano Zampini PetscBool issbaij; 316304708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3164f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 31658ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 3166f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 3167f4ddd8eeSStefano Zampini PetscInt nn_R; 316881d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 3169f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3170f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 3171f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 3172f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 3173f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3174f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3175f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 3176727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 3177f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3178f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3179f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 3180f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 3181f4ddd8eeSStefano Zampini } 3182f4ddd8eeSStefano Zampini } 3183f4ddd8eeSStefano Zampini /* last check */ 3184d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 3185f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3186f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3187f4ddd8eeSStefano Zampini } 3188f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 3189f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3190f4ddd8eeSStefano Zampini } 3191a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 3192af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 3193af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 319404708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 319504708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 319604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 319704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 319804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 3199af732b37SStefano Zampini } else { 3200511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 32016816873aSStefano Zampini } 320204708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 320304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 320404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 320504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 320604708bb6SStefano Zampini } else { 3207511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 320804708bb6SStefano Zampini } 320904708bb6SStefano Zampini } 3210a00504b5SStefano Zampini /* extract A_RR */ 3211b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3212a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3213a00504b5SStefano Zampini 3214a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 321516e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3216a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 321716e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 321816e386b8SStefano Zampini } else { 3219a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 3220a00504b5SStefano Zampini } 3221a00504b5SStefano Zampini } else { 3222a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3223a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 3224a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3225a00504b5SStefano Zampini } 3226a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 3227f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 322816e386b8SStefano Zampini } 32293301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 32303301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 32316816873aSStefano Zampini } 3232f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 3233304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 3234304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 3235304d26faSStefano Zampini /* default */ 3236304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 3237e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 3238304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 32399577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 32409577ea80SStefano Zampini if (issbaij) { 32419577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 32429577ea80SStefano Zampini } else { 3243304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 32449577ea80SStefano Zampini } 3245304d26faSStefano Zampini /* Allow user's customization */ 3246304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 3247304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3248304d26faSStefano Zampini } 3249304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3250304d26faSStefano Zampini if (!n_R) { 3251304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 3252304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3253304d26faSStefano Zampini } 32545cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 3255df4d28bfSStefano Zampini /* Reuse solver if it is present */ 3256b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3257df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3258d62866d3SStefano Zampini 3259df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 3260d62866d3SStefano Zampini } 3261304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 3262304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 3263684f6988SStefano Zampini } 3264304d26faSStefano Zampini 3265684f6988SStefano Zampini if (pcbddc->dbg_flag) { 3266684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 32671575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3268684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3269684f6988SStefano Zampini } 3270c7017625SStefano Zampini 3271c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 3272c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 3273c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 3274c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 3275c7017625SStefano Zampini } 3276c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 3277c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 3278c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 3279c7017625SStefano Zampini } 3280c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 3281c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 3282c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 3283c7017625SStefano Zampini } 3284c7017625SStefano Zampini 3285c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 3286c7017625SStefano Zampini if (pcbddc->dbg_flag) { 3287684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 32880fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 32890fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 32900fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 32910fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 32920fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 3293e604994aSStefano 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); 3294c7017625SStefano Zampini if (check_corr[0]) { 3295c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 3296c7017625SStefano Zampini } 3297304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3298304d26faSStefano Zampini } 3299684f6988SStefano Zampini if (neumann) { /* Neumann */ 33000fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 33010fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 33020fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 33030fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 33040fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 3305e604994aSStefano 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); 3306c7017625SStefano Zampini if (check_corr[1]) { 3307c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 3308c7017625SStefano Zampini } 3309304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3310304d26faSStefano Zampini } 3311684f6988SStefano Zampini } 33125cbda25cSStefano Zampini /* free Neumann problem's matrix */ 33135cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3314304d26faSStefano Zampini PetscFunctionReturn(0); 3315304d26faSStefano Zampini } 3316304d26faSStefano Zampini 3317304d26faSStefano Zampini #undef __FUNCT__ 3318ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 331980677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 3320674ae819SStefano Zampini { 3321674ae819SStefano Zampini PetscErrorCode ierr; 3322674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3323be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3324b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 3325674ae819SStefano Zampini 3326674ae819SStefano Zampini PetscFunctionBegin; 3327b334f244SStefano Zampini if (!reuse_solver) { 332880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 332920c7b377SStefano Zampini } 333080677318SStefano Zampini if (!pcbddc->switch_static) { 333180677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 333280677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 333380677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 333420c7b377SStefano Zampini } 3335b334f244SStefano Zampini if (!reuse_solver) { 333680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 333780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 333820c7b377SStefano Zampini } else { 3339df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3340be83ff47SStefano Zampini 3341df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3342df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 334320c7b377SStefano Zampini } 3344be83ff47SStefano Zampini } else { 334580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 334680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 334780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 334880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 334980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 335080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 335180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 335280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 335380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3354674ae819SStefano Zampini } 3355674ae819SStefano Zampini } 3356b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 335780677318SStefano Zampini if (applytranspose) { 335880677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 335980677318SStefano Zampini } else { 336080677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 336180677318SStefano Zampini } 3362be83ff47SStefano Zampini } else { 3363df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3364be83ff47SStefano Zampini 3365be83ff47SStefano Zampini if (applytranspose) { 3366df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3367be83ff47SStefano Zampini } else { 3368df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3369be83ff47SStefano Zampini } 3370be83ff47SStefano Zampini } 337180677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 337280677318SStefano Zampini if (!pcbddc->switch_static) { 3373b334f244SStefano Zampini if (!reuse_solver) { 337480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 337580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3376be83ff47SStefano Zampini } else { 3377df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3378be83ff47SStefano Zampini 3379df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3380df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3381be83ff47SStefano Zampini } 338280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 338380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 338480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 338580677318SStefano Zampini } 338680677318SStefano Zampini } else { 338780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 339080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 339180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 339280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 339380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 339480677318SStefano Zampini } 339580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 339680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 339780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 339880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3399674ae819SStefano Zampini } 3400674ae819SStefano Zampini PetscFunctionReturn(0); 3401674ae819SStefano Zampini } 3402674ae819SStefano Zampini 3403dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 3404674ae819SStefano Zampini #undef __FUNCT__ 3405674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 3406dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 3407674ae819SStefano Zampini { 3408674ae819SStefano Zampini PetscErrorCode ierr; 3409674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3410674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 3411674ae819SStefano Zampini const PetscScalar zero = 0.0; 3412674ae819SStefano Zampini 3413674ae819SStefano Zampini PetscFunctionBegin; 3414dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 34154fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3416dc359a40SStefano Zampini if (applytranspose) { 3417674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 34188eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 3419dc359a40SStefano Zampini } else { 3420674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 3421674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 342215aaf578SStefano Zampini } 34234fee134fSStefano Zampini } else { 34244fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 34254fee134fSStefano Zampini } 3426efc2fbd9SStefano Zampini 3427efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 34284f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3429efc2fbd9SStefano Zampini PetscScalar *array; 34304f1b2e48SStefano Zampini PetscInt j; 3431efc2fbd9SStefano Zampini 3432efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 34334f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 3434efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3435efc2fbd9SStefano Zampini } 3436efc2fbd9SStefano Zampini 343712edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 343812edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 343912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 344012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 344112edc857SStefano Zampini 34429f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 344312edc857SStefano Zampini if (pcbddc->coarse_ksp) { 344451694757SStefano Zampini Mat coarse_mat; 3445964fefecSStefano Zampini Vec rhs,sol; 344651694757SStefano Zampini MatNullSpace nullsp; 344727b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 3448964fefecSStefano Zampini 344927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 345027b6a85dSStefano Zampini PC coarse_pc; 345127b6a85dSStefano Zampini 345227b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 345327b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 345427b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 345527b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 345627b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 345727b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 34583bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 345927b6a85dSStefano Zampini } 346027b6a85dSStefano Zampini } 3461964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 3462964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 346351694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 346451694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 346551694757SStefano Zampini if (nullsp) { 346651694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 346751694757SStefano Zampini } 346812edc857SStefano Zampini if (applytranspose) { 3469*9a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 3470964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 34712701bc32SStefano Zampini } else { 34721f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 34732701bc32SStefano Zampini PC coarse_pc; 34742701bc32SStefano Zampini 34752701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 34762701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 34773e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 34782701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 347912edc857SStefano Zampini } else { 3480964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 348112edc857SStefano Zampini } 34822701bc32SStefano Zampini } 34831d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 348427b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 348527b6a85dSStefano Zampini PC coarse_pc; 348627b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 348727b6a85dSStefano Zampini 348827b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 348927b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 349027b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 34913bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 349227b6a85dSStefano Zampini } 349351694757SStefano Zampini if (nullsp) { 349451694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 349551694757SStefano Zampini } 349612edc857SStefano Zampini } 3497674ae819SStefano Zampini 3498674ae819SStefano Zampini /* Local solution on R nodes */ 34994fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 350080677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 35019f00e9b4SStefano Zampini } 35029f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 35039f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 350412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3505674ae819SStefano Zampini 35064fee134fSStefano Zampini /* Sum contributions from the two levels */ 35074fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3508dc359a40SStefano Zampini if (applytranspose) { 3509dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3510dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3511dc359a40SStefano Zampini } else { 3512674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 35138eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3514dc359a40SStefano Zampini } 3515efc2fbd9SStefano Zampini /* store p0 */ 35164f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3517efc2fbd9SStefano Zampini PetscScalar *array; 35184f1b2e48SStefano Zampini PetscInt j; 3519efc2fbd9SStefano Zampini 3520efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 35214f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 3522efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3523efc2fbd9SStefano Zampini } 35244fee134fSStefano Zampini } else { /* expand the coarse solution */ 35254fee134fSStefano Zampini if (applytranspose) { 35264fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 35274fee134fSStefano Zampini } else { 35284fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 35294fee134fSStefano Zampini } 35304fee134fSStefano Zampini } 3531674ae819SStefano Zampini PetscFunctionReturn(0); 3532674ae819SStefano Zampini } 3533674ae819SStefano Zampini 3534674ae819SStefano Zampini #undef __FUNCT__ 3535674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 353612edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 3537674ae819SStefano Zampini { 3538674ae819SStefano Zampini PetscErrorCode ierr; 3539674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 354058da7f69SStefano Zampini PetscScalar *array; 354112edc857SStefano Zampini Vec from,to; 3542674ae819SStefano Zampini 3543674ae819SStefano Zampini PetscFunctionBegin; 354412edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 354512edc857SStefano Zampini from = pcbddc->coarse_vec; 354612edc857SStefano Zampini to = pcbddc->vec1_P; 354712edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 354812edc857SStefano Zampini Vec tvec; 354958da7f69SStefano Zampini 355058da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 355158da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 355212edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 355358da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 355458da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 355558da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 355612edc857SStefano Zampini } 355712edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 355812edc857SStefano Zampini from = pcbddc->vec1_P; 355912edc857SStefano Zampini to = pcbddc->coarse_vec; 356012edc857SStefano Zampini } 356112edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3562674ae819SStefano Zampini PetscFunctionReturn(0); 3563674ae819SStefano Zampini } 3564674ae819SStefano Zampini 3565674ae819SStefano Zampini #undef __FUNCT__ 3566674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 356712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3568674ae819SStefano Zampini { 3569674ae819SStefano Zampini PetscErrorCode ierr; 3570674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 357158da7f69SStefano Zampini PetscScalar *array; 357212edc857SStefano Zampini Vec from,to; 3573674ae819SStefano Zampini 3574674ae819SStefano Zampini PetscFunctionBegin; 357512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 357612edc857SStefano Zampini from = pcbddc->coarse_vec; 357712edc857SStefano Zampini to = pcbddc->vec1_P; 357812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 357912edc857SStefano Zampini from = pcbddc->vec1_P; 358012edc857SStefano Zampini to = pcbddc->coarse_vec; 358112edc857SStefano Zampini } 358212edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 358312edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 358412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 358512edc857SStefano Zampini Vec tvec; 358658da7f69SStefano Zampini 358712edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 358858da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 358958da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 359058da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 359158da7f69SStefano Zampini } 359258da7f69SStefano Zampini } else { 359358da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 359458da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 359512edc857SStefano Zampini } 359612edc857SStefano Zampini } 3597674ae819SStefano Zampini PetscFunctionReturn(0); 3598674ae819SStefano Zampini } 3599674ae819SStefano Zampini 3600984c4197SStefano Zampini /* uncomment for testing purposes */ 3601984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3602674ae819SStefano Zampini #undef __FUNCT__ 3603674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3604674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3605674ae819SStefano Zampini { 3606674ae819SStefano Zampini PetscErrorCode ierr; 3607674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3608674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3609674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3610984c4197SStefano Zampini /* one and zero */ 3611984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3612984c4197SStefano Zampini /* space to store constraints and their local indices */ 36139162d606SStefano Zampini PetscScalar *constraints_data; 36149162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 36159162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 36169162d606SStefano Zampini PetscInt *constraints_n; 3617984c4197SStefano Zampini /* iterators */ 3618b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3619984c4197SStefano Zampini /* BLAS integers */ 3620e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3621e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3622c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3623727cdba6SStefano Zampini /* reuse */ 36240e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 36250e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3626984c4197SStefano Zampini /* change of basis */ 3627b3d85658SStefano Zampini PetscBool qr_needed; 36289162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3629984c4197SStefano Zampini /* auxiliary stuff */ 363064efe560SStefano Zampini PetscInt *nnz,*is_indices; 36318a0068c3SStefano Zampini PetscInt ncc; 3632984c4197SStefano Zampini /* some quantities */ 363345a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3634a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3635984c4197SStefano Zampini 3636674ae819SStefano Zampini PetscFunctionBegin; 36378e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 36388e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 36398e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 364016909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 3641088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3642088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 36430e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 36440e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 36450e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 36460e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 36470e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3648088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3649cf5a6209SStefano Zampini 3650cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 36519162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3652cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3653cf5a6209SStefano Zampini const Vec *nearnullvecs; 3654cf5a6209SStefano Zampini Vec *localnearnullsp; 3655cf5a6209SStefano Zampini PetscScalar *array; 3656cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3657cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3658674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3659b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3660674ae819SStefano Zampini PetscScalar *work; 3661674ae819SStefano Zampini PetscReal *singular_vals; 3662674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3663674ae819SStefano Zampini PetscReal *rwork; 3664674ae819SStefano Zampini #endif 3665674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3666674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3667674ae819SStefano Zampini #else 3668964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3669964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3670674ae819SStefano Zampini #endif 3671674ae819SStefano Zampini 3672674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3673d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3674e4d548c7SStefano Zampini /* print some info */ 36751f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 3676e4d548c7SStefano Zampini PetscInt nv; 3677e4d548c7SStefano Zampini 3678e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 3679e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 3680e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3681e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3682e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3683e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 3684e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 3685e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3686e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3687e4d548c7SStefano Zampini } 3688e4d548c7SStefano Zampini 3689d06fc5fdSStefano Zampini /* free unneeded index sets */ 3690d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3691d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3692674ae819SStefano Zampini } 3693d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3694d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3695d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3696d06fc5fdSStefano Zampini } 3697d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3698d06fc5fdSStefano Zampini n_ISForEdges = 0; 3699d06fc5fdSStefano Zampini } 3700d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3701d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3702d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3703d06fc5fdSStefano Zampini } 3704d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3705d06fc5fdSStefano Zampini n_ISForFaces = 0; 3706d06fc5fdSStefano Zampini } 370770022509SStefano Zampini 3708674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3709674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3710674ae819SStefano Zampini if (nearnullsp) { 3711674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3712f4ddd8eeSStefano Zampini /* remove any stored info */ 3713f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3714f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3715f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3716f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3717f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3718473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3719f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3720f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3721f4ddd8eeSStefano Zampini } 3722984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3723984c4197SStefano Zampini nnsp_size = 0; 3724674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3725674ae819SStefano Zampini } 3726984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3727984c4197SStefano Zampini max_constraints = nnsp_size; 3728984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3729984c4197SStefano Zampini 3730674ae819SStefano Zampini /* 3731674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 37329162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 37339162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 37349162d606SStefano Zampini There can be multiple constraints per connected component 3735674ae819SStefano Zampini */ 3736674ae819SStefano Zampini n_vertices = 0; 3737674ae819SStefano Zampini if (ISForVertices) { 3738674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3739674ae819SStefano Zampini } 37409162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 37419162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 37429162d606SStefano Zampini 37439162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 37449162d606SStefano Zampini total_counts *= max_constraints; 3745674ae819SStefano Zampini total_counts += n_vertices; 37464641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 37479162d606SStefano Zampini 3748674ae819SStefano Zampini total_counts = 0; 3749674ae819SStefano Zampini max_size_of_constraint = 0; 3750674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 37519162d606SStefano Zampini IS used_is; 3752674ae819SStefano Zampini if (i<n_ISForEdges) { 37539162d606SStefano Zampini used_is = ISForEdges[i]; 3754674ae819SStefano Zampini } else { 37559162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3756674ae819SStefano Zampini } 37579162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3758674ae819SStefano Zampini total_counts += j; 3759674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3760674ae819SStefano Zampini } 37619162d606SStefano 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); 37629162d606SStefano Zampini 3763984c4197SStefano Zampini /* get local part of global near null space vectors */ 3764785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3765984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3766984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3767e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3768e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3769984c4197SStefano Zampini } 3770674ae819SStefano Zampini 3771242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3772242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3773a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3774242a89d7SStefano Zampini 3775984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3776a773dcb8SStefano Zampini if (!skip_lapack) { 3777674ae819SStefano Zampini PetscScalar temp_work; 3778911cabfeSStefano Zampini 3779674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3780984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3781785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3782785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3783785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3784674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3785785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3786674ae819SStefano Zampini #endif 3787674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3788c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3789c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3790674ae819SStefano Zampini lwork = -1; 3791674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3792674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3793c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3794674ae819SStefano Zampini #else 3795c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3796674ae819SStefano Zampini #endif 3797674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3798984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3799674ae819SStefano Zampini #else /* on missing GESVD */ 3800674ae819SStefano Zampini /* SVD */ 3801674ae819SStefano Zampini PetscInt max_n,min_n; 3802674ae819SStefano Zampini max_n = max_size_of_constraint; 3803984c4197SStefano Zampini min_n = max_constraints; 3804984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3805674ae819SStefano Zampini min_n = max_size_of_constraint; 3806984c4197SStefano Zampini max_n = max_constraints; 3807674ae819SStefano Zampini } 3808785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3809674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3810785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3811674ae819SStefano Zampini #endif 3812674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3813674ae819SStefano Zampini lwork = -1; 3814e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3815e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3816b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3817674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3818674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 38199162d606SStefano 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)); 3820674ae819SStefano Zampini #else 38219162d606SStefano 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)); 3822674ae819SStefano Zampini #endif 3823674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3824984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3825984c4197SStefano Zampini #endif /* on missing GESVD */ 3826674ae819SStefano Zampini /* Allocate optimal workspace */ 3827674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3828854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3829674ae819SStefano Zampini } 3830674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3831674ae819SStefano Zampini total_counts = 0; 38329162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 38339162d606SStefano Zampini constraints_data_ptr[0] = 0; 3834674ae819SStefano Zampini /* vertices */ 38359162d606SStefano Zampini if (n_vertices) { 3836674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 38379162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3838674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 38399162d606SStefano Zampini constraints_n[total_counts] = 1; 38409162d606SStefano Zampini constraints_data[total_counts] = 1.0; 38419162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 38429162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3843674ae819SStefano Zampini total_counts++; 3844674ae819SStefano Zampini } 3845674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3846674ae819SStefano Zampini n_vertices = total_counts; 3847674ae819SStefano Zampini } 3848984c4197SStefano Zampini 3849674ae819SStefano Zampini /* edges and faces */ 38509162d606SStefano Zampini total_counts_cc = total_counts; 3851911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 38529162d606SStefano Zampini IS used_is; 38539162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 38549162d606SStefano Zampini 3855911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 38569162d606SStefano Zampini used_is = ISForEdges[ncc]; 3857984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3858674ae819SStefano Zampini } else { 38599162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3860984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3861674ae819SStefano Zampini } 3862674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 38639162d606SStefano Zampini 38649162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 38659162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3866984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3867984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3868674ae819SStefano Zampini if (nnsp_has_cnst) { 38695b08dc53SStefano Zampini PetscScalar quad_value; 38709162d606SStefano Zampini 38719162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 38729162d606SStefano Zampini idxs_copied = PETSC_TRUE; 38739162d606SStefano Zampini 3874a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3875674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3876a773dcb8SStefano Zampini } else { 3877a773dcb8SStefano Zampini quad_value = 1.0; 3878a773dcb8SStefano Zampini } 3879674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 38809162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3881674ae819SStefano Zampini } 38829162d606SStefano Zampini temp_constraints++; 3883674ae819SStefano Zampini total_counts++; 3884674ae819SStefano Zampini } 3885674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3886984c4197SStefano Zampini PetscReal real_value; 38879162d606SStefano Zampini PetscScalar *ptr_to_data; 38889162d606SStefano Zampini 3889984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 38909162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3891674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 38929162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3893674ae819SStefano Zampini } 3894984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3895984c4197SStefano Zampini /* check if array is null on the connected component */ 3896e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 38979162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 38985b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3899674ae819SStefano Zampini temp_constraints++; 3900674ae819SStefano Zampini total_counts++; 39019162d606SStefano Zampini if (!idxs_copied) { 39029162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 39039162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3904674ae819SStefano Zampini } 3905674ae819SStefano Zampini } 39069162d606SStefano Zampini } 39079162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 390845a1bb75SStefano Zampini valid_constraints = temp_constraints; 3909eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3910a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 39119162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 39129162d606SStefano Zampini 39139162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3914a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39159162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3916a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 39179162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3918a773dcb8SStefano Zampini } else { /* perform SVD */ 3919984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 39209162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3921674ae819SStefano Zampini 3922674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3923984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3924984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3925984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3926984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3927984c4197SStefano Zampini from that computed using LAPACKgesvd 3928984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3929984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3930984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3931674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3932e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3933984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3934674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3935674ae819SStefano Zampini for (k=0;k<j+1;k++) { 39369162d606SStefano 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)); 3937674ae819SStefano Zampini } 3938674ae819SStefano Zampini } 3939e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3940e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3941e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3942674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3943c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3944674ae819SStefano Zampini #else 3945c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3946674ae819SStefano Zampini #endif 3947674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3948984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3949984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3950674ae819SStefano Zampini j = 0; 3951984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3952674ae819SStefano Zampini total_counts = total_counts-j; 395345a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3954e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3955c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3956c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3957c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3958c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3959c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3960c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3961674ae819SStefano Zampini if (j<temp_constraints) { 3962984c4197SStefano Zampini PetscInt ii; 3963984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3964674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39659162d606SStefano 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)); 3966674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3967984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3968674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 39699162d606SStefano 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]; 3970674ae819SStefano Zampini } 3971674ae819SStefano Zampini } 3972674ae819SStefano Zampini } 3973674ae819SStefano Zampini #else /* on missing GESVD */ 3974e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3975e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3976b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3977674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3978674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 39799162d606SStefano 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)); 3980674ae819SStefano Zampini #else 39819162d606SStefano 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)); 3982674ae819SStefano Zampini #endif 3983984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3984674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3985984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3986e310c8b4SStefano Zampini k = temp_constraints; 3987e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3988674ae819SStefano Zampini j = 0; 3989e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 399045a1bb75SStefano Zampini valid_constraints = k-j; 3991911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3992984c4197SStefano Zampini #endif /* on missing GESVD */ 3993674ae819SStefano Zampini } 3994a773dcb8SStefano Zampini } 39959162d606SStefano Zampini /* update pointers information */ 39969162d606SStefano Zampini if (valid_constraints) { 39979162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 39989162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 39999162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 40009162d606SStefano Zampini /* set change_of_basis flag */ 400145a1bb75SStefano Zampini if (boolforchange) { 4002b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 40039162d606SStefano Zampini } 4004b3d85658SStefano Zampini total_counts_cc++; 400545a1bb75SStefano Zampini } 400645a1bb75SStefano Zampini } 4007984c4197SStefano Zampini /* free workspace */ 40088f1c130eSStefano Zampini if (!skip_lapack) { 4009984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4010984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4011984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 4012984c4197SStefano Zampini #endif 4013984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 4014984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4015984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 4016984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 4017984c4197SStefano Zampini #endif 4018984c4197SStefano Zampini } 4019984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4020984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 4021984c4197SStefano Zampini } 4022984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 4023cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 4024cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4025cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4026cf5a6209SStefano Zampini } 4027cf5a6209SStefano Zampini if (n_ISForFaces) { 4028cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4029cf5a6209SStefano Zampini } 4030cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4031cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4032cf5a6209SStefano Zampini } 4033cf5a6209SStefano Zampini if (n_ISForEdges) { 4034cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4035cf5a6209SStefano Zampini } 4036cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 403708122e43SStefano Zampini } else { 403808122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4039984c4197SStefano Zampini 404008122e43SStefano Zampini total_counts = 0; 404108122e43SStefano Zampini n_vertices = 0; 4042d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 4043d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 404408122e43SStefano Zampini } 404508122e43SStefano Zampini max_constraints = 0; 40469162d606SStefano Zampini total_counts_cc = 0; 404708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 404808122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 40499162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 405008122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 405108122e43SStefano Zampini } 40529162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 40539162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 40549162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 40559162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 405674d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 40579162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 40589162d606SStefano Zampini total_counts_cc = 0; 40599162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 40609162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 40619162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 406208122e43SStefano Zampini } 406308122e43SStefano Zampini } 40649162d606SStefano Zampini #if 0 40659162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 40669162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 40679162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 40689162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 40699162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 40709162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 40719162d606SStefano Zampini } 40729162d606SStefano Zampini printf("\n"); 40739162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 40749162d606SStefano Zampini } 40751b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 40768bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 40771b968477SStefano Zampini } 40781b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 40798bec7fa6SStefano 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]); 40801b968477SStefano Zampini } 408108122e43SStefano Zampini #endif 408208122e43SStefano Zampini 40838bec7fa6SStefano Zampini max_size_of_constraint = 0; 40849162d606SStefano 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]); 40859162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 408608122e43SStefano Zampini /* Change of basis */ 4087b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 408808122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 408908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 409008122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 4091b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 409208122e43SStefano Zampini } 409308122e43SStefano Zampini } 409408122e43SStefano Zampini } 409508122e43SStefano Zampini } 4096984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 40974f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 409808122e43SStefano Zampini 40999162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 41009162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 41016c4ed002SBarry 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); 4102674ae819SStefano Zampini 4103674ae819SStefano Zampini /* Create constraint matrix */ 4104674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 410516f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 4106984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 4107984c4197SStefano Zampini 4108984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 4109a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 4110a717540cSStefano Zampini qr_needed = PETSC_FALSE; 411174d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 4112984c4197SStefano Zampini total_primal_vertices=0; 4113b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 41149162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 41159162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 411672b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 41179162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 4118b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 411964efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 41209162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 41219162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 4122a717540cSStefano Zampini } 4123b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 412491af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 4125a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 4126a717540cSStefano Zampini qr_needed = PETSC_TRUE; 4127a717540cSStefano Zampini } 4128fa434743SStefano Zampini } else { 4129b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 4130fa434743SStefano Zampini } 4131a717540cSStefano Zampini } 4132b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 4133b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 4134674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 413570022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4136b3d85658SStefano Zampini 41374f1b2e48SStefano 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); 41380e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 41390e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 4140984c4197SStefano Zampini 4141984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 414274d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 4143785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 4144984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 414574d5cdf7SStefano Zampini 4146984c4197SStefano Zampini j = total_primal_vertices; 414774d5cdf7SStefano Zampini total_counts = total_primal_vertices; 4148b3d85658SStefano Zampini cum = total_primal_vertices; 41499162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 41504641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 4151b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 4152b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 4153b3d85658SStefano Zampini cum++; 41549162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 415574d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 415674d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 415774d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 415874d5cdf7SStefano Zampini } 41599162d606SStefano Zampini j += constraints_n[i]; 4160674ae819SStefano Zampini } 4161674ae819SStefano Zampini } 4162674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 4163674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 4164088faed8SStefano Zampini 4165674ae819SStefano Zampini /* set values in constraint matrix */ 4166984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 41670e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4168674ae819SStefano Zampini } 4169984c4197SStefano Zampini total_counts = total_primal_vertices; 41709162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 41714641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 41729162d606SStefano Zampini PetscInt *cols; 41739162d606SStefano Zampini 41749162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 41759162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 41769162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 41779162d606SStefano Zampini PetscInt row = total_counts+k; 41789162d606SStefano Zampini PetscScalar *vals; 41799162d606SStefano Zampini 41809162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 41819162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 41829162d606SStefano Zampini } 41839162d606SStefano Zampini total_counts += constraints_n[i]; 4184674ae819SStefano Zampini } 4185674ae819SStefano Zampini } 4186674ae819SStefano Zampini /* assembling */ 4187674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4188674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4189088faed8SStefano Zampini 4190984c4197SStefano Zampini /* 41916a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4192984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 4193f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 4194984c4197SStefano Zampini */ 4195674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 4196674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 4197026de310SStefano Zampini /* dual and primal dofs on a single cc */ 4198984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 4199984c4197SStefano Zampini /* working stuff for GEQRF */ 420081d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 4201984c4197SStefano Zampini PetscBLASInt lqr_work; 4202984c4197SStefano Zampini /* working stuff for UNGQR */ 4203984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 4204984c4197SStefano Zampini PetscBLASInt lgqr_work; 4205984c4197SStefano Zampini /* working stuff for TRTRS */ 4206984c4197SStefano Zampini PetscScalar *trs_rhs; 42073f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 4208984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 4209984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 4210984c4197SStefano Zampini PetscScalar *start_vals; 4211984c4197SStefano Zampini /* working stuff for values insertion */ 42124641a718SStefano Zampini PetscBT is_primal; 421364efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 4214906d46d4SStefano Zampini /* matrix sizes */ 4215906d46d4SStefano Zampini PetscInt global_size,local_size; 4216906d46d4SStefano Zampini /* temporary change of basis */ 4217906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 4218cf5a6209SStefano Zampini /* extra space for debugging */ 4219cf5a6209SStefano Zampini PetscScalar *dbg_work; 4220984c4197SStefano Zampini 4221906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 4222906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 422316f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 4224bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 4225906d46d4SStefano Zampini /* nonzeros for local mat */ 4226bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 42271dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4228bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 42291dd7afcfSStefano Zampini } else { 42301dd7afcfSStefano Zampini const PetscInt *ii; 42311dd7afcfSStefano Zampini PetscInt n; 42321dd7afcfSStefano Zampini PetscBool flg_row; 42331dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 42341dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 42351dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 42361dd7afcfSStefano Zampini } 42379162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 4238a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 42399162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 4240a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 42419162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 4242a717540cSStefano Zampini } else { 42439162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 42449162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 4245a717540cSStefano Zampini } 4246a717540cSStefano Zampini } 4247a717540cSStefano Zampini } 4248906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 4249bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 42501dd7afcfSStefano Zampini /* Set interior change in the matrix */ 42511dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4252bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 4253906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 4254a717540cSStefano Zampini } 42551dd7afcfSStefano Zampini } else { 42561dd7afcfSStefano Zampini const PetscInt *ii,*jj; 42571dd7afcfSStefano Zampini PetscScalar *aa; 42581dd7afcfSStefano Zampini PetscInt n; 42591dd7afcfSStefano Zampini PetscBool flg_row; 42601dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 42611dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 42621dd7afcfSStefano Zampini for (i=0;i<n;i++) { 42631dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 42641dd7afcfSStefano Zampini } 42651dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 42661dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 42671dd7afcfSStefano Zampini } 4268a717540cSStefano Zampini 4269a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4270a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4271a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4272a717540cSStefano Zampini } 4273a717540cSStefano Zampini 4274a717540cSStefano Zampini 4275a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 4276a717540cSStefano Zampini /* 4277a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 4278a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 4279a717540cSStefano Zampini 4280a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 4281a717540cSStefano Zampini 4282a6b551f4SStefano 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) 4283a6b551f4SStefano Zampini 4284a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 4285a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 4286a717540cSStefano Zampini | ... | 4287a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 4288a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 4289a717540cSStefano Zampini 4290a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 4291a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 4292a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 4293a6b551f4SStefano Zampini 4294a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 4295a717540cSStefano Zampini */ 4296a717540cSStefano Zampini if (qr_needed) { 4297984c4197SStefano Zampini /* space to store Q */ 4298854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 4299984c4197SStefano Zampini /* first we issue queries for optimal work */ 43003f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 43013f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 43023f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4303984c4197SStefano Zampini lqr_work = -1; 43043f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 4305984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 4306984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 4307785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 4308984c4197SStefano Zampini lgqr_work = -1; 43093f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 43103f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 43113f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 43123f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 43133f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 43143f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 4315984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 4316984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 4317785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 4318984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 4319785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 4320984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 4321785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 4322a717540cSStefano Zampini /* allocating workspace for check */ 4323a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4324cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 4325a717540cSStefano Zampini } 4326a717540cSStefano Zampini } 4327984c4197SStefano Zampini /* array to store whether a node is primal or not */ 43284641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 4329473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 43300e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 43316c4ed002SBarry 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); 433239e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 433339e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 433439e2fb2aSStefano Zampini } 433539e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 4336984c4197SStefano Zampini 4337a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 43389162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 43399162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 43404641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 4341984c4197SStefano Zampini /* get constraint info */ 43429162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 4343984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 4344984c4197SStefano Zampini 4345984c4197SStefano Zampini if (pcbddc->dbg_flag) { 43469162d606SStefano 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); 4347674ae819SStefano Zampini } 4348984c4197SStefano Zampini 4349fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 4350a717540cSStefano Zampini 4351a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 4352a717540cSStefano Zampini if (pcbddc->dbg_flag) { 43539162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4354a717540cSStefano Zampini } 4355984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 43569162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4357984c4197SStefano Zampini 4358984c4197SStefano Zampini /* compute QR decomposition of constraints */ 43593f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 43603f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 43613f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4362674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43633f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 4364984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 4365674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4366984c4197SStefano Zampini 4367984c4197SStefano Zampini /* explictly compute R^-T */ 4368984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 4369984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 43703f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 43713f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 43723f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 43733f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 4374984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43753f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 4376984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 4377984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4378984c4197SStefano Zampini 4379a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 43803f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 43813f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 43823f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 43833f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4384984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43853f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 4386984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 4387984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4388984c4197SStefano Zampini 4389984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 4390984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 4391984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 43923f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 43933f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 43943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 43953f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 43963f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 43973f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 4398984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43999162d606SStefano 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)); 4400984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 44019162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4402984c4197SStefano Zampini 4403984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 44049162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 4405984c4197SStefano Zampini /* insert cols for primal dofs */ 4406984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 4407984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 44089162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4409906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4410984c4197SStefano Zampini } 4411984c4197SStefano Zampini /* insert cols for dual dofs */ 4412984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 44139162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 4414984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 44159162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4416906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4417984c4197SStefano Zampini j++; 4418674ae819SStefano Zampini } 4419674ae819SStefano Zampini } 4420984c4197SStefano Zampini 4421984c4197SStefano Zampini /* check change of basis */ 4422984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4423984c4197SStefano Zampini PetscInt ii,jj; 4424984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 4425c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 4426c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4427c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 4428c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4429c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 4430c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 4431984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4432cf5a6209SStefano 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)); 4433984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4434984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4435984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4436cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 4437cf5a6209SStefano 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; 4438674ae819SStefano Zampini } 4439674ae819SStefano Zampini } 4440984c4197SStefano Zampini if (!valid_qr) { 444122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 4442984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4443984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4444cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 4445cf5a6209SStefano 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])); 4446674ae819SStefano Zampini } 4447cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 4448cf5a6209SStefano 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])); 4449984c4197SStefano Zampini } 4450984c4197SStefano Zampini } 4451984c4197SStefano Zampini } 4452674ae819SStefano Zampini } else { 445322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 4454674ae819SStefano Zampini } 4455674ae819SStefano Zampini } 4456a717540cSStefano Zampini } else { /* simple transformation block */ 4457a717540cSStefano Zampini PetscInt row,col; 4458a6b551f4SStefano Zampini PetscScalar val,norm; 4459a6b551f4SStefano Zampini 4460a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 44619162d606SStefano 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)); 4462a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 44639162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 44649162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4465bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 44669162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 4467906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 44689162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 4469a717540cSStefano Zampini } else { 4470a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 44719162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4472a717540cSStefano Zampini if (row != col) { 44739162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 4474a717540cSStefano Zampini } else { 44759162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 4476a717540cSStefano Zampini } 4477906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 4478a717540cSStefano Zampini } 4479a717540cSStefano Zampini } 4480a717540cSStefano Zampini } 448198a51de6SStefano Zampini if (pcbddc->dbg_flag) { 448222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 4483a717540cSStefano Zampini } 4484674ae819SStefano Zampini } 4485984c4197SStefano Zampini } else { 4486984c4197SStefano Zampini if (pcbddc->dbg_flag) { 44879162d606SStefano 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); 4488674ae819SStefano Zampini } 4489674ae819SStefano Zampini } 4490674ae819SStefano Zampini } 4491a717540cSStefano Zampini 4492a717540cSStefano Zampini /* free workspace */ 4493a717540cSStefano Zampini if (qr_needed) { 4494984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4495cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 4496984c4197SStefano Zampini } 4497984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 4498984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 4499984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 4500984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 4501984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 4502674ae819SStefano Zampini } 4503a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 4504906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4505906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4506906d46d4SStefano Zampini 4507906d46d4SStefano Zampini /* assembling of global change of variable */ 450888c03ad3SStefano Zampini if (!pcbddc->fake_change) { 4509bbb9e6c6SStefano Zampini Mat tmat; 451016f15bc4SStefano Zampini PetscInt bs; 451116f15bc4SStefano Zampini 4512906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4513906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4514bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4515bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 4516bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4517bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 451816f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 451916f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 4520906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4521bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 4522bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4523bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4524bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4525bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4526e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4527e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4528bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 4529bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 453088c03ad3SStefano Zampini 4531906d46d4SStefano Zampini /* check */ 4532906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4533906d46d4SStefano Zampini PetscReal error; 4534906d46d4SStefano Zampini Vec x,x_change; 4535906d46d4SStefano Zampini 4536906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 4537906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 4538906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 4539906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 4540e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4541e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4542bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4543e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4544e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4545906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4546906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4547906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4548906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4549bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4550906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4551906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4552906d46d4SStefano Zampini } 4553b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4554b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4555b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4556bf3a8328SStefano Zampini 4557*9a962809SStefano Zampini if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints");CHKERRQ(ierr); 4558b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 4559ac632422SStefano Zampini Mat S_new,tmat; 4560bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 4561bbb9e6c6SStefano Zampini 4562bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 45636816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4564bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4565bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 4566bf3a8328SStefano Zampini IS is_V; 4567b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4568b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4569b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4570b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4571b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4572bf3a8328SStefano Zampini } 4573bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4574ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4575b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4576ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4577bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4578bf3a8328SStefano Zampini const PetscScalar *array; 4579bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 4580bf3a8328SStefano Zampini PetscInt i,n_V; 4581bf3a8328SStefano Zampini 4582b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4583b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4584b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4585b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4586b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4587b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4588b087196eSStefano Zampini PetscScalar val; 4589b087196eSStefano Zampini PetscInt idx; 4590b087196eSStefano Zampini 4591b087196eSStefano Zampini idx = idxs_V[i]; 4592b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4593b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4594b087196eSStefano Zampini } 4595b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4596b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4597bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4598bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4599bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4600bf3a8328SStefano Zampini } 4601ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4602ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4603ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4604ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4605b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4606ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4607bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4608b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4609bf3a8328SStefano Zampini } 4610ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4611ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4612ac632422SStefano Zampini } 4613b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 461488c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4615b96c3477SStefano Zampini } 4616c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 4617b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 4618c9db6a07SStefano Zampini PetscInt i; 4619c9db6a07SStefano Zampini 4620c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4621c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 4622c9db6a07SStefano Zampini } 4623c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 4624c9db6a07SStefano Zampini } 4625b96c3477SStefano Zampini } 462616909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 462716909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 462816909a7fSStefano Zampini } else { 4629906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 463016909a7fSStefano Zampini } 46311dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 463227b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 463372b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 463472b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 463572b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 463672b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 463772b8c272SStefano Zampini } 46381dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 463927b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 4640b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4641b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4642906d46d4SStefano Zampini } else { 46431dd7afcfSStefano Zampini Mat benign_global = NULL; 464427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 46451dd7afcfSStefano Zampini Mat tmat; 46461dd7afcfSStefano Zampini 46471dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 46481dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 46491dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 46501dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 46511dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 46521dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 46531dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46541dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46551dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 46561dd7afcfSStefano Zampini if (pcbddc->benign_change) { 46571dd7afcfSStefano Zampini Mat M; 46581dd7afcfSStefano Zampini 46591dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 46601dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 46611dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 46621dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4663906d46d4SStefano Zampini } else { 46641dd7afcfSStefano Zampini Mat eye; 46651dd7afcfSStefano Zampini PetscScalar *array; 46661dd7afcfSStefano Zampini 46671dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 46681dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 46691dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 46701dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 4671906d46d4SStefano Zampini } 46721dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 46731dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46741dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46751dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 46761dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 46771dd7afcfSStefano Zampini } 46781dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 46791dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 46801dd7afcfSStefano Zampini } 46811dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 46821dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 46831dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 468427b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 46851dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 46861dd7afcfSStefano Zampini } 46871dd7afcfSStefano Zampini } 468816909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 468916909a7fSStefano Zampini IS is_global; 469016909a7fSStefano Zampini const PetscInt *gidxs; 469116909a7fSStefano Zampini 469216909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 469316909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 469416909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 469516909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 469616909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 469716909a7fSStefano Zampini } 46981dd7afcfSStefano Zampini } 46991dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 47001dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 4701b9b85e73SStefano Zampini } 4702a717540cSStefano Zampini 470372b8c272SStefano Zampini if (!pcbddc->fake_change) { 47044f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 47054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 47064f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 47074f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4708019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4709019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4710019a44ceSStefano Zampini pcbddc->local_primal_size++; 4711019a44ceSStefano Zampini } 4712019a44ceSStefano Zampini 4713019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4714727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4715727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 47169f47a83aSStefano 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); 4717c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 47180e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 47199f47a83aSStefano 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); 4720727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4721727cdba6SStefano Zampini } 47220e6343abSStefano Zampini } 4723727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4724b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 472572b8c272SStefano Zampini } 472672b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4727727cdba6SStefano Zampini 4728a717540cSStefano Zampini /* flush dbg viewer */ 4729b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4730b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4731b8ffe317SStefano Zampini } 4732a717540cSStefano Zampini 4733e310c8b4SStefano Zampini /* free workspace */ 4734a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 47354641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 473608122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 47379162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 47389162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 473908122e43SStefano Zampini } else { 47409162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 47419162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 47429162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 474308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 474408122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 47459162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 47469162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 474708122e43SStefano Zampini } 4748674ae819SStefano Zampini PetscFunctionReturn(0); 4749674ae819SStefano Zampini } 4750674ae819SStefano Zampini 4751674ae819SStefano Zampini #undef __FUNCT__ 4752674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4753674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4754674ae819SStefano Zampini { 4755674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4756674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4757674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 475814f95afaSStefano Zampini PetscInt ierr,i,N; 4759674ae819SStefano Zampini 4760674ae819SStefano Zampini PetscFunctionBegin; 47618e61c736SStefano Zampini /* Reset previously computed graph */ 47628e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4763674ae819SStefano Zampini /* Init local Graph struct */ 47647fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 47653bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4766674ae819SStefano Zampini 4767575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 4768*9a962809SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) 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); 47699577ea80SStefano Zampini 4770674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 4771d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 47724d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 47734d379d7bSStefano Zampini PetscInt nvtxs; 4774e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4775674ae819SStefano Zampini 47762fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 47772fffb893SStefano Zampini if (flg_row) { 47784d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4779b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 47802fffb893SStefano Zampini } 47812fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4782674ae819SStefano Zampini } 47839b28b941SStefano Zampini if (pcbddc->dbg_flag) { 47849b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4785674ae819SStefano Zampini } 4786674ae819SStefano Zampini 4787674ae819SStefano Zampini /* Setup of Graph */ 47884b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 478914f95afaSStefano 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); 4790674ae819SStefano Zampini 47914f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 47924f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 47934f1b2e48SStefano Zampini PetscInt *local_subs; 47944f1b2e48SStefano Zampini 47954f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 47964f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 47974f1b2e48SStefano Zampini const PetscInt *idxs; 47984f1b2e48SStefano Zampini PetscInt nl,j; 47994f1b2e48SStefano Zampini 48004f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 48014f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 48024f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 48034f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 48044f1b2e48SStefano Zampini } 48054f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 48064f1b2e48SStefano Zampini } 48074f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 48084f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 48094f1b2e48SStefano Zampini } 48104f1b2e48SStefano Zampini 4811674ae819SStefano Zampini /* Graph's connected components analysis */ 4812674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4813674ae819SStefano Zampini PetscFunctionReturn(0); 4814674ae819SStefano Zampini } 4815674ae819SStefano Zampini 48169a7d3425SStefano Zampini #undef __FUNCT__ 48179a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 48189a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 48199a7d3425SStefano Zampini { 48209a7d3425SStefano Zampini PetscInt i,j; 48219a7d3425SStefano Zampini PetscScalar *alphas; 48229a7d3425SStefano Zampini PetscErrorCode ierr; 48239a7d3425SStefano Zampini 48249a7d3425SStefano Zampini PetscFunctionBegin; 4825785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 48269a7d3425SStefano Zampini for (i=0;i<n;i++) { 48279a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 4828669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 4829669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 4830669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 48319a7d3425SStefano Zampini } 48329a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 48339a7d3425SStefano Zampini PetscFunctionReturn(0); 48349a7d3425SStefano Zampini } 48359a7d3425SStefano Zampini 4836e7931f94SStefano Zampini #undef __FUNCT__ 483770cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 483857de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 4839e7931f94SStefano Zampini { 484057de7509SStefano Zampini Mat A; 4841e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4842e7931f94SStefano Zampini PetscMPIInt size,rank,color; 484352e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 484452e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 484527b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 484657de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 484727b6a85dSStefano Zampini PetscInt xadj_count, *count; 484827b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 484927b6a85dSStefano Zampini PetscSubcomm psubcomm; 485027b6a85dSStefano Zampini MPI_Comm subcomm; 485152e5ac9dSStefano Zampini PetscErrorCode ierr; 4852a57a6d2fSStefano Zampini 4853e7931f94SStefano Zampini PetscFunctionBegin; 485457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 485557de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 485657de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 485757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 485857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 485957de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 486057de7509SStefano Zampini 486157de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 486257de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 486357de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 486457de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 486557de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 486657de7509SStefano Zampini im_active = !!(n); 486757de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 486857de7509SStefano Zampini void_procs = size - active_procs; 486957de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 487057de7509SStefano Zampini if (void_procs) { 487157de7509SStefano Zampini PetscInt ncand; 487257de7509SStefano Zampini 487357de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 487457de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 487557de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 487657de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 487757de7509SStefano Zampini if (!procs_candidates[i]) { 487857de7509SStefano Zampini procs_candidates[ncand++] = i; 487957de7509SStefano Zampini } 488057de7509SStefano Zampini } 488157de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 488257de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 488357de7509SStefano Zampini } 488457de7509SStefano Zampini 488557de7509SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix */ 488657de7509SStefano Zampini if (active_procs < *n_subdomains) { 488757de7509SStefano Zampini PetscInt issize,isidx; 488857de7509SStefano Zampini if (im_active) { 488957de7509SStefano Zampini issize = 1; 489057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 489157de7509SStefano Zampini isidx = procs_candidates[rank]; 489257de7509SStefano Zampini } else { 489357de7509SStefano Zampini isidx = rank; 489457de7509SStefano Zampini } 489557de7509SStefano Zampini } else { 489657de7509SStefano Zampini issize = 0; 489757de7509SStefano Zampini isidx = -1; 489857de7509SStefano Zampini } 489957de7509SStefano Zampini *n_subdomains = active_procs; 490057de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 4901daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 490257de7509SStefano Zampini PetscFunctionReturn(0); 490357de7509SStefano Zampini } 4904c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 4905c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 490627b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 4907e7931f94SStefano Zampini 4908e7931f94SStefano Zampini /* Get info on mapping */ 49093bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 49103bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4911e7931f94SStefano Zampini 4912e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4913785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4914e7931f94SStefano Zampini xadj[0] = 0; 4915e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4916785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4917785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 491827b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 491927b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 492027b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 492127b6a85dSStefano Zampini count[shared[i][j]] += 1; 4922e7931f94SStefano Zampini 492327b6a85dSStefano Zampini xadj_count = 0; 49242b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 492527b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 492627b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 4927d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4928d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4929d023bfaeSStefano Zampini xadj_count++; 493027b6a85dSStefano Zampini break; 493127b6a85dSStefano Zampini } 4932e7931f94SStefano Zampini } 4933e7931f94SStefano Zampini } 4934d023bfaeSStefano Zampini xadj[1] = xadj_count; 493527b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 49363bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4937e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4938e7931f94SStefano Zampini 49393837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4940e7931f94SStefano Zampini 494127b6a85dSStefano Zampini /* Restrict work on active processes only */ 494227b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 494327b6a85dSStefano Zampini if (void_procs) { 494427b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 494527b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 494627b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 494727b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 494827b6a85dSStefano Zampini } else { 494927b6a85dSStefano Zampini psubcomm = NULL; 495027b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 495127b6a85dSStefano Zampini } 495227b6a85dSStefano Zampini 495327b6a85dSStefano Zampini v_wgt = NULL; 495427b6a85dSStefano Zampini if (!color) { 4955e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4956e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4957e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4958c8587f34SStefano Zampini } else { 495952e5ac9dSStefano Zampini Mat subdomain_adj; 496052e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 496152e5ac9dSStefano Zampini MatPartitioning partitioner; 496227b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 496352e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 496457de7509SStefano Zampini PetscMPIInt size; 4965b0c7d250SStefano Zampini PetscBool aggregate; 4966b0c7d250SStefano Zampini 496727b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 496827b6a85dSStefano Zampini if (void_procs) { 496927b6a85dSStefano Zampini PetscInt prank = rank; 4970785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 497127b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 4972e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4973e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4974c8587f34SStefano Zampini } 4975e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 497627b6a85dSStefano Zampini } else { 497727b6a85dSStefano Zampini oldranks = NULL; 497827b6a85dSStefano Zampini } 4979b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 498027b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 4981b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4982b0c7d250SStefano Zampini PetscMPIInt nrank; 4983b0c7d250SStefano Zampini PetscScalar *vals; 4984b0c7d250SStefano Zampini 498527b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 4986b0c7d250SStefano Zampini lrows = 0; 4987b0c7d250SStefano Zampini if (nrank<redprocs) { 4988b0c7d250SStefano Zampini lrows = size/redprocs; 4989b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4990b0c7d250SStefano Zampini } 499127b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4992b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4993b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4994b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4995b0c7d250SStefano Zampini row = nrank; 4996b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4997b0c7d250SStefano Zampini cols = adjncy; 4998b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4999b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 5000b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 5001b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5002b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 500352e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 500452e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 500552e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5006b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 500727b6a85dSStefano Zampini if (use_vwgt) { 500827b6a85dSStefano Zampini Vec v; 500927b6a85dSStefano Zampini const PetscScalar *array; 501027b6a85dSStefano Zampini PetscInt nl; 501127b6a85dSStefano Zampini 501227b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 501327b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 501427b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 501527b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 501627b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 501727b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 501827b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 501922db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 502027b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 502127b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 502227b6a85dSStefano Zampini } 5023b0c7d250SStefano Zampini } else { 502427b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 502527b6a85dSStefano Zampini if (use_vwgt) { 502627b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 502727b6a85dSStefano Zampini v_wgt[0] = local_size; 502827b6a85dSStefano Zampini } 5029b0c7d250SStefano Zampini } 503022b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 5031e7931f94SStefano Zampini 5032e7931f94SStefano Zampini /* Partition */ 503327b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 5034e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 503527b6a85dSStefano Zampini if (v_wgt) { 5036e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 5037c8587f34SStefano Zampini } 503857de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 503957de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 5040e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 5041e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 504222b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 5043e7931f94SStefano Zampini 504452e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 50456583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 504652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 504752e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 504857de7509SStefano Zampini if (!aggregate) { 504957de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 505027b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 505127b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 505227b6a85dSStefano Zampini #endif 505357de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 505427b6a85dSStefano Zampini } else if (oldranks) { 5055b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 505627b6a85dSStefano Zampini } else { 505727b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 505857de7509SStefano Zampini } 505928143c3dSStefano Zampini } else { 5060b0c7d250SStefano Zampini PetscInt idxs[1]; 5061b0c7d250SStefano Zampini PetscMPIInt tag; 5062b0c7d250SStefano Zampini MPI_Request *reqs; 5063b0c7d250SStefano Zampini 5064b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 5065b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 5066b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 506727b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 506828143c3dSStefano Zampini } 506927b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 5070b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5071b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 507257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 507327b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 507427b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 507527b6a85dSStefano Zampini #endif 507657de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 507727b6a85dSStefano Zampini } else if (oldranks) { 5078b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 507927b6a85dSStefano Zampini } else { 508027b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 5081e7931f94SStefano Zampini } 508257de7509SStefano Zampini } 508352e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5084e7931f94SStefano Zampini /* clean up */ 5085e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 508652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 5087e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 5088e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 5089e7931f94SStefano Zampini } 509027b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 509157de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 5092e7931f94SStefano Zampini 5093e7931f94SStefano Zampini /* assemble parallel IS for sends */ 5094e7931f94SStefano Zampini i = 1; 509527b6a85dSStefano Zampini if (!color) i=0; 509657de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 5097e7931f94SStefano Zampini PetscFunctionReturn(0); 5098e7931f94SStefano Zampini } 5099e7931f94SStefano Zampini 5100e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 5101e7931f94SStefano Zampini 5102e7931f94SStefano Zampini #undef __FUNCT__ 5103e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 51041ae86dd6SStefano 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[]) 5105e7931f94SStefano Zampini { 510670cf5478SStefano Zampini Mat local_mat; 5107e7931f94SStefano Zampini IS is_sends_internal; 51089d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 51091ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 51109d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 5111e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 5112e7931f94SStefano Zampini PetscInt* l2gmap_indices; 5113e7931f94SStefano Zampini const PetscInt* is_indices; 5114e7931f94SStefano Zampini MatType new_local_type; 5115e7931f94SStefano Zampini /* buffers */ 5116e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 511728143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 51189d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 5119e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 51201ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 5121e7931f94SStefano Zampini /* MPI */ 512228143c3dSStefano Zampini MPI_Comm comm,comm_n; 512328143c3dSStefano Zampini PetscSubcomm subcomm; 5124e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 512528143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 512628143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 51271ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 51281ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 51291ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 5130e7931f94SStefano Zampini PetscErrorCode ierr; 5131e7931f94SStefano Zampini 5132e7931f94SStefano Zampini PetscFunctionBegin; 513357de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5134e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 513528143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 513657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 513757de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 513857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 513957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 514057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 51411ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 51421ae86dd6SStefano Zampini if (nvecs) { 51431ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 51441ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 51451ae86dd6SStefano Zampini } 514657de7509SStefano Zampini /* further checks */ 5147e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5148e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 5149e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 5150e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 5151e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 515257de7509SStefano Zampini if (reuse && *mat_n) { 515370cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 515457de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 515570cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 515628143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 515770cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 515870cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 515970cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 516070cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 516170cf5478SStefano Zampini } 5162e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 5163e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 516457de7509SStefano Zampini 5165e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 5166e7931f94SStefano Zampini if (!is_sends) { 516728143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 516857de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 5169c8587f34SStefano Zampini } else { 5170e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 5171e7931f94SStefano Zampini is_sends_internal = is_sends; 5172c8587f34SStefano Zampini } 5173e7931f94SStefano Zampini 5174e7931f94SStefano Zampini /* get comm */ 5175a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 5176e7931f94SStefano Zampini 5177e7931f94SStefano Zampini /* compute number of sends */ 5178e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 5179e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 5180e7931f94SStefano Zampini 5181e7931f94SStefano Zampini /* compute number of receives */ 5182e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 5183785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 5184e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 5185e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5186e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 5187e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 5188e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 5189e7931f94SStefano Zampini 519028143c3dSStefano Zampini /* restrict comm if requested */ 519128143c3dSStefano Zampini subcomm = 0; 519228143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 519328143c3dSStefano Zampini if (restrict_comm) { 5194779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 5195779c1cceSStefano Zampini 519628143c3dSStefano Zampini color = 0; 519753a05cb3SStefano Zampini if (restrict_full) { 519853a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 519953a05cb3SStefano Zampini } else { 520053a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 520153a05cb3SStefano Zampini } 5202b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 520328143c3dSStefano Zampini subcommsize = commsize - subcommsize; 520428143c3dSStefano Zampini /* check if reuse has been requested */ 520557de7509SStefano Zampini if (reuse) { 520628143c3dSStefano Zampini if (*mat_n) { 520728143c3dSStefano Zampini PetscMPIInt subcommsize2; 520828143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 520928143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 521028143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 521128143c3dSStefano Zampini } else { 521228143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 521328143c3dSStefano Zampini } 521428143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 5215779c1cceSStefano Zampini PetscMPIInt rank; 5216779c1cceSStefano Zampini 5217779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 521828143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 521928143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 522028143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 5221306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 522228143c3dSStefano Zampini } 522328143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 522428143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 522528143c3dSStefano Zampini } else { 522628143c3dSStefano Zampini comm_n = comm; 522728143c3dSStefano Zampini } 522828143c3dSStefano Zampini 5229e7931f94SStefano Zampini /* prepare send/receive buffers */ 5230785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 5231e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 5232785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 5233e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 523428143c3dSStefano Zampini if (nis) { 5235854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 523628143c3dSStefano Zampini } 5237e7931f94SStefano Zampini 523828143c3dSStefano Zampini /* Get data from local matrices */ 52396c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 5240e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 5241e7931f94SStefano Zampini /* 5242e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 5243e7931f94SStefano Zampini send_buffer_idxs should contain: 5244e7931f94SStefano Zampini - MatType_PRIVATE type 5245e7931f94SStefano Zampini - PetscInt size_of_l2gmap 5246e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 5247e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 5248e7931f94SStefano Zampini */ 52496c4ed002SBarry Smith else { 5250e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 52513bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 5252854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 5253e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 5254e7931f94SStefano Zampini send_buffer_idxs[1] = i; 52553bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5256e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 52573bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5258e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 5259e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5260e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 5261e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 5262c8587f34SStefano Zampini } 5263c8587f34SStefano Zampini } 5264e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 526528143c3dSStefano Zampini /* additional is (if any) */ 526628143c3dSStefano Zampini if (nis) { 526728143c3dSStefano Zampini PetscMPIInt psum; 526828143c3dSStefano Zampini PetscInt j; 526928143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 527028143c3dSStefano Zampini PetscInt plen; 527128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 527228143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 527328143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 527428143c3dSStefano Zampini } 5275854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 527628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 527728143c3dSStefano Zampini PetscInt plen; 527828143c3dSStefano Zampini const PetscInt *is_array_idxs; 527928143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 528028143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 528128143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 528228143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 528328143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 528428143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 528528143c3dSStefano Zampini } 528628143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 528728143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 528828143c3dSStefano Zampini } 528928143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 529028143c3dSStefano Zampini } 529128143c3dSStefano Zampini 5292e7931f94SStefano Zampini buf_size_idxs = 0; 5293e7931f94SStefano Zampini buf_size_vals = 0; 529428143c3dSStefano Zampini buf_size_idxs_is = 0; 52951ae86dd6SStefano Zampini buf_size_vecs = 0; 5296e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5297e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 5298e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 529928143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 53001ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 5301e7931f94SStefano Zampini } 5302785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 5303785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 530495ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 53051ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 5306e7931f94SStefano Zampini 5307e7931f94SStefano Zampini /* get new tags for clean communications */ 5308e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 5309e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 531028143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 53111ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 5312e7931f94SStefano Zampini 5313e7931f94SStefano Zampini /* allocate for requests */ 5314785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 5315785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 531695ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 53171ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 5318785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 5319785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 532095ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 53211ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 5322e7931f94SStefano Zampini 5323e7931f94SStefano Zampini /* communications */ 5324e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5325e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 532628143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 53271ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 5328e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5329e7931f94SStefano Zampini source_dest = onodes[i]; 5330e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 5331e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 5332e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5333e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 533428143c3dSStefano Zampini if (nis) { 533557de7509SStefano Zampini source_dest = onodes_is[i]; 533628143c3dSStefano 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); 533728143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 533828143c3dSStefano Zampini } 53391ae86dd6SStefano Zampini if (nvecs) { 53401ae86dd6SStefano Zampini source_dest = onodes[i]; 53411ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 53421ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 53431ae86dd6SStefano Zampini } 5344e7931f94SStefano Zampini } 5345e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5346e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 5347e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 5348e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 534928143c3dSStefano Zampini if (nis) { 535028143c3dSStefano 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); 535128143c3dSStefano Zampini } 53521ae86dd6SStefano Zampini if (nvecs) { 53531ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 53541ae86dd6SStefano 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); 53551ae86dd6SStefano Zampini } 5356e7931f94SStefano Zampini } 5357e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5358e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 5359e7931f94SStefano Zampini 5360e7931f94SStefano Zampini /* assemble new l2g map */ 5361e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5362e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 53639d30be91SStefano Zampini new_local_rows = 0; 5364e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 53659d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5366e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5367e7931f94SStefano Zampini } 53689d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 5369e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 53709d30be91SStefano Zampini new_local_rows = 0; 5371e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 53729d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 53739d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5374e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5375e7931f94SStefano Zampini } 53769d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 53779d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 5378e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 5379e7931f94SStefano Zampini 5380e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 5381e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 5382e7931f94SStefano 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) */ 5383e7931f94SStefano Zampini if (n_recvs) { 538428143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 5385e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5386e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5387e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 5388e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 5389e7931f94SStefano Zampini break; 5390e7931f94SStefano Zampini } 5391e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5392e7931f94SStefano Zampini } 5393e7931f94SStefano Zampini switch (new_local_type_private) { 539428143c3dSStefano Zampini case MATDENSE_PRIVATE: 539528143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 5396e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5397e7931f94SStefano Zampini bs = 1; 539828143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 539928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 540028143c3dSStefano Zampini bs = 1; 540128143c3dSStefano Zampini } 5402e7931f94SStefano Zampini break; 5403e7931f94SStefano Zampini case MATAIJ_PRIVATE: 5404e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5405e7931f94SStefano Zampini bs = 1; 5406e7931f94SStefano Zampini break; 5407e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 5408e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 5409e7931f94SStefano Zampini break; 5410e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 5411e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 5412e7931f94SStefano Zampini break; 5413e7931f94SStefano Zampini default: 54149d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 5415e7931f94SStefano Zampini break; 5416e7931f94SStefano Zampini } 541728143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 541828143c3dSStefano Zampini new_local_type = MATSEQDENSE; 541928143c3dSStefano Zampini bs = 1; 5420e7931f94SStefano Zampini } 5421e7931f94SStefano Zampini 542270cf5478SStefano Zampini /* create MATIS object if needed */ 542357de7509SStefano Zampini if (!reuse) { 5424e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 5425e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 542670cf5478SStefano Zampini } else { 542770cf5478SStefano Zampini /* it also destroys the local matrices */ 542857de7509SStefano Zampini if (*mat_n) { 542970cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 543057de7509SStefano Zampini } else { /* this is a fake object */ 543157de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 543257de7509SStefano Zampini } 543370cf5478SStefano Zampini } 543470cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 5435e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 54369d30be91SStefano Zampini 54379d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 54389d30be91SStefano Zampini 54399d30be91SStefano Zampini /* Global to local map of received indices */ 54409d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 54419d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 54429d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 54439d30be91SStefano Zampini 54449d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 54459d30be91SStefano Zampini buf_size_idxs = 0; 54469d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 54479d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 54489d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 54499d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 54509d30be91SStefano Zampini } 54519d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 54529d30be91SStefano Zampini 54539d30be91SStefano Zampini /* set preallocation */ 54549d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 54559d30be91SStefano Zampini if (!newisdense) { 54569d30be91SStefano Zampini PetscInt *new_local_nnz=0; 54579d30be91SStefano Zampini 54589d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 54599d30be91SStefano Zampini if (n_recvs) { 54609d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 54619d30be91SStefano Zampini } 54629d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 54639d30be91SStefano Zampini PetscInt j; 54649d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 54659d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 54669d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 54679d30be91SStefano Zampini } 54689d30be91SStefano Zampini } else { 54699d30be91SStefano Zampini /* TODO */ 54709d30be91SStefano Zampini } 54719d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 54729d30be91SStefano Zampini } 54739d30be91SStefano Zampini if (new_local_nnz) { 54749d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 54759d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 54769d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 54779d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 54789d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 54799d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 54809d30be91SStefano Zampini } else { 54819d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 54829d30be91SStefano Zampini } 54839d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 54849d30be91SStefano Zampini } else { 54859d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 54869d30be91SStefano Zampini } 5487e7931f94SStefano Zampini 5488e7931f94SStefano Zampini /* set values */ 5489e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 54909d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5491e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5492e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5493e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 54949d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5495e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5496e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5497e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 549828143c3dSStefano Zampini } else { 549928143c3dSStefano Zampini /* TODO */ 5500e7931f94SStefano Zampini } 5501e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5502e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5503e7931f94SStefano Zampini } 5504e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5505e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 550670cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 550770cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55089d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 5509e7931f94SStefano Zampini 5510dfd14d43SStefano Zampini #if 0 551128143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5512e7931f94SStefano Zampini Vec lvec,rvec; 5513e7931f94SStefano Zampini PetscReal infty_error; 5514e7931f94SStefano Zampini 55152a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5516e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5517e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5518e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 551970cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5520e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5521e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5522e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5523e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5524e7931f94SStefano Zampini } 552528143c3dSStefano Zampini #endif 5526e7931f94SStefano Zampini 552728143c3dSStefano Zampini /* assemble new additional is (if any) */ 552828143c3dSStefano Zampini if (nis) { 552928143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 553028143c3dSStefano Zampini 553128143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5532854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 553328143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 553428143c3dSStefano Zampini psum = 0; 553528143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 553628143c3dSStefano Zampini for (j=0;j<nis;j++) { 553728143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 553828143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 553928143c3dSStefano Zampini psum += plen; 554028143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 554128143c3dSStefano Zampini } 554228143c3dSStefano Zampini } 5543854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5544854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 554528143c3dSStefano Zampini for (i=1;i<nis;i++) { 554628143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 554728143c3dSStefano Zampini } 554828143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 554928143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 555028143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 555128143c3dSStefano Zampini for (j=0;j<nis;j++) { 555228143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 555328143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 555428143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 555528143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 555628143c3dSStefano Zampini } 555728143c3dSStefano Zampini } 555828143c3dSStefano Zampini for (i=0;i<nis;i++) { 555928143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 556028143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 556128143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 556228143c3dSStefano Zampini } 556328143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 556428143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 556528143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 556628143c3dSStefano Zampini } 5567e7931f94SStefano Zampini /* free workspace */ 556828143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5569e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5570e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5571e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5572e7931f94SStefano Zampini if (isdense) { 5573e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5574e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5575e7931f94SStefano Zampini } else { 5576e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5577e7931f94SStefano Zampini } 557828143c3dSStefano Zampini if (nis) { 557928143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 558028143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 558128143c3dSStefano Zampini } 55821ae86dd6SStefano Zampini 55831ae86dd6SStefano Zampini if (nvecs) { 55841ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 55851ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 55861ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 55871ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 55881ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 55891ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 55901ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 55911ae86dd6SStefano Zampini /* set values */ 55921ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 55931ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 55941ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 55951ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 55961ae86dd6SStefano Zampini PetscInt j; 55971ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 55981ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 55991ae86dd6SStefano Zampini } 56001ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 56011ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 56021ae86dd6SStefano Zampini } 56031ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 56041ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 56051ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 56061ae86dd6SStefano Zampini } 56071ae86dd6SStefano Zampini 56081ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 56091ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5610e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5611e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 56121ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 561328143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5614e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5615e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 56161ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 561728143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5618e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5619e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5620e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5621e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5622e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 562328143c3dSStefano Zampini if (nis) { 562428143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 562528143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 562628143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 562728143c3dSStefano Zampini } 562828143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 562928143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 563028143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 563128143c3dSStefano Zampini for (i=0;i<nis;i++) { 563228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 563328143c3dSStefano Zampini } 56341ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 56351ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 56361ae86dd6SStefano Zampini } 563753a05cb3SStefano Zampini *mat_n = NULL; 563828143c3dSStefano Zampini } 5639e7931f94SStefano Zampini PetscFunctionReturn(0); 5640e7931f94SStefano Zampini } 5641a57a6d2fSStefano Zampini 564212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5643af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 564412edc857SStefano Zampini 5645c8587f34SStefano Zampini #undef __FUNCT__ 5646c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5647c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5648c8587f34SStefano Zampini { 5649c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5650c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 565120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 56521ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 56539881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 565420a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 56556e683305SStefano Zampini IS coarse_is,*isarray; 56566e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 565730368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5658f9eb5b7dSStefano Zampini PC pc_temp; 5659c8587f34SStefano Zampini PCType coarse_pc_type; 5660c8587f34SStefano Zampini KSPType coarse_ksp_type; 5661f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 56624f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 56636e683305SStefano Zampini Mat t_coarse_mat_is; 566457de7509SStefano Zampini PetscInt ncoarse; 566568457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 566622bc73bbSStefano Zampini PetscScalar *array; 566757de7509SStefano Zampini MatReuse coarse_mat_reuse; 566857de7509SStefano Zampini PetscBool restr, full_restr, have_void; 56699881197aSStefano Zampini PetscErrorCode ierr; 5670fdc09c96SStefano Zampini 5671c8587f34SStefano Zampini PetscFunctionBegin; 5672c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 567368457ee5SStefano 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 */ 5674fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 56755a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5676fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5677f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5678f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5679f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5680fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 568151bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 568251bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5683dc4bcba2SStefano Zampini PC pc; 5684dc4bcba2SStefano Zampini PetscBool isbddc; 5685dc4bcba2SStefano Zampini 5686dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5687dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5688dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5689dc4bcba2SStefano Zampini if (isbddc) { 569063c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 569163c961adSStefano Zampini } else { 5692727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 569363c961adSStefano Zampini } 5694fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5695fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5696fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5697f4ddd8eeSStefano Zampini } 5698fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5699fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5700f4ddd8eeSStefano Zampini } 570170cf5478SStefano Zampini /* reset any subassembling information */ 570257de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 570370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 570457de7509SStefano Zampini } 57056e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5706fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5707f4ddd8eeSStefano Zampini } 570857de7509SStefano Zampini /* assemble coarse matrix */ 570957de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 571057de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 571157de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 571257de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 571318a45a71SStefano Zampini } else { 571457de7509SStefano Zampini coarse_mat = NULL; 571557de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 57166e683305SStefano Zampini } 5717e7931f94SStefano Zampini 5718abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5719abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5720abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5721abbbba34SStefano Zampini 5722abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 572322bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 572422bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 572522bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 572622bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5727e176bc59SStefano 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); 57286e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 57296e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 57306e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5731abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5732abbbba34SStefano Zampini 573357de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 573457de7509SStefano Zampini im_active = !!(pcis->n); 573557de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 573657de7509SStefano Zampini 573757de7509SStefano Zampini /* determine number of process partecipating to coarse solver and compute subassembling pattern */ 573857de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 573957de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 574057de7509SStefano Zampini coarse_mat_is = NULL; 574157de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 574257de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 574357de7509SStefano Zampini full_restr = PETSC_TRUE; 57441ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 574557de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 574657de7509SStefano Zampini if (multilevel_requested) { 574757de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 574857de7509SStefano Zampini restr = PETSC_FALSE; 574957de7509SStefano Zampini full_restr = PETSC_FALSE; 575057de7509SStefano Zampini } else { 575157de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 575257de7509SStefano Zampini restr = PETSC_TRUE; 575357de7509SStefano Zampini full_restr = PETSC_TRUE; 575457de7509SStefano Zampini } 57554b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 575657de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 575757de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 5758a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 575957de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 5760a198735bSStefano Zampini } else { 5761a198735bSStefano Zampini PetscMPIInt size,rank; 5762a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 5763a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 5764a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 5765a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 5766a198735bSStefano Zampini } 576757de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 576857de7509SStefano Zampini PetscInt psum; 576957de7509SStefano Zampini PetscMPIInt size; 577057de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 577157de7509SStefano Zampini else psum = 0; 577257de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 577357de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 577457de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 577557de7509SStefano Zampini } 577657de7509SStefano Zampini /* determine if we can go multilevel */ 577757de7509SStefano Zampini if (multilevel_requested) { 577857de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 577957de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 578057de7509SStefano Zampini } 578157de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 578257de7509SStefano Zampini 5783e4d548c7SStefano Zampini /* dump subassembling pattern */ 5784e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 5785e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 5786e4d548c7SStefano Zampini } 5787e4d548c7SStefano Zampini 57886e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 578927b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 57906e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 57916e683305SStefano Zampini const PetscInt *idxs; 57926e683305SStefano Zampini ISLocalToGlobalMapping tmap; 57936e683305SStefano Zampini 57946e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 57950be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 57966e683305SStefano Zampini /* allocate space for temporary storage */ 5797854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5798854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 57996e683305SStefano Zampini /* allocate for IS array */ 58006e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 58016e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 580227b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 580330368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5804854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 58056e683305SStefano Zampini /* dofs splitting */ 58066e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 58076e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 58086e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 58096e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 58106e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 58116e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 58126e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 581330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 58146e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 58156e683305SStefano Zampini } 58166e683305SStefano Zampini /* neumann boundaries */ 58176e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 58186e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 58196e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 58206e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 58216e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 58226e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 58236e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 582430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 58256e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 58266e683305SStefano Zampini } 58276e683305SStefano Zampini /* free memory */ 58286e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 58296e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 58306e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 58316e683305SStefano Zampini } else { 58326e683305SStefano Zampini nis = 0; 58336e683305SStefano Zampini nisdofs = 0; 58346e683305SStefano Zampini nisneu = 0; 583530368db7SStefano Zampini nisvert = 0; 58366e683305SStefano Zampini isarray = NULL; 58376e683305SStefano Zampini } 58386e683305SStefano Zampini /* destroy no longer needed map */ 58396e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 58406e683305SStefano Zampini 584157de7509SStefano Zampini /* subassemble */ 584257de7509SStefano Zampini if (multilevel_allowed) { 58431ae86dd6SStefano Zampini Vec vp[1]; 58441ae86dd6SStefano Zampini PetscInt nvecs = 0; 584557de7509SStefano Zampini PetscBool reuse,reuser; 58461ae86dd6SStefano Zampini 584757de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 584857de7509SStefano Zampini else reuse = PETSC_FALSE; 584957de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 58501ae86dd6SStefano Zampini vp[0] = NULL; 58511ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 58521ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 58531ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 58541ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 58551ae86dd6SStefano Zampini nvecs = 1; 58561ae86dd6SStefano Zampini 58571ae86dd6SStefano Zampini if (pcbddc->divudotp) { 5858a198735bSStefano Zampini Mat B,loc_divudotp; 58591ae86dd6SStefano Zampini Vec v,p; 58601ae86dd6SStefano Zampini IS dummy; 58611ae86dd6SStefano Zampini PetscInt np; 58621ae86dd6SStefano Zampini 5863a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 5864a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 58651ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 5866a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 58671ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 58681ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 58691ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 58701ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 58711ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 58721ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 58731ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 58741ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 58751ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 58761ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 58771ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 58781ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 587974e2c79eSStefano Zampini } 58801ae86dd6SStefano Zampini } 58811ae86dd6SStefano Zampini if (reuser) { 58821ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 588374e2c79eSStefano Zampini } else { 58841ae86dd6SStefano 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); 58851ae86dd6SStefano Zampini } 58861ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 58871ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 58881ae86dd6SStefano Zampini PetscInt nl; 58891ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 58901ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 58911ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 58921ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 58931ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 58941ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 58951ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 58961ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 5897a198735bSStefano Zampini } else { 5898a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 58991ae86dd6SStefano Zampini } 59001ae86dd6SStefano Zampini } else { 59011ae86dd6SStefano 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); 59026e683305SStefano Zampini } 590357de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 590457de7509SStefano Zampini PetscMPIInt size; 590557de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 590657de7509SStefano Zampini if (!multilevel_allowed) { 590757de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 59086e683305SStefano Zampini } else { 590957de7509SStefano Zampini Mat A; 5910779c1cceSStefano Zampini 591157de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 591257de7509SStefano Zampini if (coarse_mat_is) { 591357de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 591457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 591557de7509SStefano Zampini coarse_mat = coarse_mat_is; 591657de7509SStefano Zampini } 591757de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 591857de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 591957de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 5920779c1cceSStefano Zampini } 5921779c1cceSStefano Zampini } 592257de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 592357de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 59246e683305SStefano Zampini 59256e683305SStefano Zampini /* create local to global scatters for coarse problem */ 592668457ee5SStefano Zampini if (compute_vecs) { 59276e683305SStefano Zampini PetscInt lrows; 59286e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 592957de7509SStefano Zampini if (coarse_mat) { 593057de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 59316e683305SStefano Zampini } else { 59326e683305SStefano Zampini lrows = 0; 59336e683305SStefano Zampini } 59346e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 59356e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 59366e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 59376e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 59386e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 59396e683305SStefano Zampini } 59406e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 5941c8587f34SStefano Zampini 5942f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5943f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5944f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5945f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5946f9eb5b7dSStefano Zampini } else { 5947f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5948f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5949c8587f34SStefano Zampini } 5950c8587f34SStefano Zampini 59516e683305SStefano Zampini /* print some info if requested */ 59526e683305SStefano Zampini if (pcbddc->dbg_flag) { 59536e683305SStefano Zampini if (!multilevel_allowed) { 59546e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 59556e683305SStefano Zampini if (multilevel_requested) { 59566e683305SStefano 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); 59576e683305SStefano Zampini } else if (pcbddc->max_levels) { 59586e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 59596e683305SStefano Zampini } 59606e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 59616e683305SStefano Zampini } 59626e683305SStefano Zampini } 59636e683305SStefano Zampini 5964f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 596557de7509SStefano Zampini if (coarse_mat) { 59666a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 59676e683305SStefano Zampini if (pcbddc->dbg_flag) { 596857de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 59696e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 59706e683305SStefano Zampini } 5971f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5972312be037SStefano Zampini char prefix[256],str_level[16]; 5973e604994aSStefano Zampini size_t len; 597457de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5975422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5976c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5977f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 597857de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5979c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 59806e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5981c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5982c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5983e604994aSStefano Zampini /* prefix */ 5984e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5985e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5986e604994aSStefano Zampini if (!pcbddc->current_level) { 5987e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5988e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5989c8587f34SStefano Zampini } else { 5990e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5991312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5992312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 599334d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5994312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5995e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5996e604994aSStefano Zampini } 5997e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 59983e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 59993e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 60003e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 60013e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 6002f9eb5b7dSStefano Zampini /* allow user customization */ 6003f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 60043e3c6dadSStefano Zampini } 60053e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 600651bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 60073e3c6dadSStefano Zampini if (nisdofs) { 60083e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 60093e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 60103e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 60113e3c6dadSStefano Zampini } 60123e3c6dadSStefano Zampini } 60133e3c6dadSStefano Zampini if (nisneu) { 60143e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 60153e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 6016312be037SStefano Zampini } 601730368db7SStefano Zampini if (nisvert) { 601830368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 601930368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 602030368db7SStefano Zampini } 6021f9eb5b7dSStefano Zampini 6022f9eb5b7dSStefano Zampini /* get some info after set from options */ 6023f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 6024f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 60254f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 60266e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 6027f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6028f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 6029f9eb5b7dSStefano Zampini } 603039f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 60314f3a063dSStefano Zampini if (isredundant) { 60324f3a063dSStefano Zampini KSP inner_ksp; 60334f3a063dSStefano Zampini PC inner_pc; 60344f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 60354f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 60364f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 60374f3a063dSStefano Zampini } 6038f9eb5b7dSStefano Zampini 603957de7509SStefano Zampini /* parameters which miss an API */ 604057de7509SStefano Zampini if (isbddc) { 6041720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 6042720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 604357de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 604427b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 604527b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 6046a198735bSStefano Zampini Mat coarsedivudotp_is; 6047a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 6048a198735bSStefano Zampini IS row,col; 6049a198735bSStefano Zampini const PetscInt *gidxs; 6050a198735bSStefano Zampini PetscInt n,st,M,N; 6051a198735bSStefano Zampini 6052a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 6053a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 6054a198735bSStefano Zampini st = st-n; 6055a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 6056a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 6057a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 6058a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6059a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 6060a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6061a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 6062a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 6063a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 6064a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 6065a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 6066a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 6067a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 6068a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 6069a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 6070a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 6071a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6072a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6073a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 6074a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 6075a198735bSStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,NULL);CHKERRQ(ierr); 6076a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 6077720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 607859e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 6079720d30f9SStefano Zampini } 6080d4d8cf7bSStefano Zampini } 60819881197aSStefano Zampini 60823301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 60835a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 60843301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 60853301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 60863301b35fSStefano Zampini } 60873301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 60883301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 60893301b35fSStefano Zampini } 60903301b35fSStefano Zampini if (pc->pmat->spd_set) { 60913301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 60923301b35fSStefano Zampini } 609327b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 609427b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 609527b6a85dSStefano Zampini } 60966e683305SStefano Zampini /* set operators */ 60975f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 60986e683305SStefano Zampini if (pcbddc->dbg_flag) { 60996e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 61006e683305SStefano Zampini } 61016e683305SStefano Zampini } 61026e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 6103b1ecc7b1SStefano Zampini #if 0 6104b9b85e73SStefano Zampini { 6105b9b85e73SStefano Zampini PetscViewer viewer; 6106b9b85e73SStefano Zampini char filename[256]; 6107b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 6108b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 61096a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6110b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 6111f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 6112b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 6113b9b85e73SStefano Zampini } 6114b9b85e73SStefano Zampini #endif 6115f9eb5b7dSStefano Zampini 611698a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 611798a51de6SStefano Zampini Vec crhs,csol; 611804708bb6SStefano Zampini 6119f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 6120f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 6121f347579bSStefano Zampini if (!csol) { 61222a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 6123f9eb5b7dSStefano Zampini } 6124f347579bSStefano Zampini if (!crhs) { 61252a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 6126f347579bSStefano Zampini } 6127b0f5fe93SStefano Zampini } 61281ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 6129b0f5fe93SStefano Zampini 6130b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 6131b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 6132b0f5fe93SStefano Zampini 6133b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 61344f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 61354f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 61364f1b2e48SStefano Zampini } 6137b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 6138b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 6139b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6140b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6141b0f5fe93SStefano Zampini if (coarse_mat) { 6142b0f5fe93SStefano Zampini Vec nullv; 6143b0f5fe93SStefano Zampini PetscScalar *array,*array2; 6144b0f5fe93SStefano Zampini PetscInt nl; 6145b0f5fe93SStefano Zampini 6146b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 6147b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 6148b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6149b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 6150b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 6151b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 6152b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6153b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 6154b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 6155b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 6156b0f5fe93SStefano Zampini } 6157b0f5fe93SStefano Zampini } 6158b0f5fe93SStefano Zampini 6159b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 6160b0f5fe93SStefano Zampini PetscBool ispreonly; 6161b0f5fe93SStefano Zampini 6162b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6163b0f5fe93SStefano Zampini PetscBool isnull; 6164b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 6165bef83e63SStefano Zampini if (isnull) { 6166b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 6167b0f5fe93SStefano Zampini } 6168bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 6169b0f5fe93SStefano Zampini } 6170b0f5fe93SStefano Zampini /* setup coarse ksp */ 6171b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 6172cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 6173cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 61746e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 6175c8587f34SStefano Zampini KSP check_ksp; 61762b510759SStefano Zampini KSPType check_ksp_type; 6177c8587f34SStefano Zampini PC check_pc; 61786e683305SStefano Zampini Vec check_vec,coarse_vec; 61796a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 61802b510759SStefano Zampini PetscInt its; 61816e683305SStefano Zampini PetscBool compute_eigs; 61826e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 61836e683305SStefano Zampini PetscInt neigs; 61848e185a42SStefano Zampini const char *prefix; 6185c8587f34SStefano Zampini 61862b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 61876e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 6188422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 618923ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6190f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 6191e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 6192e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 6193e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 61942b510759SStefano Zampini if (ispreonly) { 61952b510759SStefano Zampini check_ksp_type = KSPPREONLY; 61966e683305SStefano Zampini compute_eigs = PETSC_FALSE; 61972b510759SStefano Zampini } else { 6198cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 61996e683305SStefano Zampini compute_eigs = PETSC_TRUE; 6200c8587f34SStefano Zampini } 6201c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 62026e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 62036e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 62046e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 6205a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 6206a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 6207a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 6208a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 6209c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 6210c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 6211c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 6212c8587f34SStefano Zampini /* create random vec */ 62132701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 6214c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 62156e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 6216c8587f34SStefano Zampini /* solve coarse problem */ 62176e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 6218cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 62196e683305SStefano Zampini if (compute_eigs) { 6220854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 6221854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 62226e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 62231ae86dd6SStefano Zampini if (neigs) { 62246e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 62256e683305SStefano Zampini lambda_min = eigs_r[0]; 62266e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 62272701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 62282701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 6229cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 6230cbcc2c2aSStefano Zampini } 6231c8587f34SStefano Zampini } 6232c8587f34SStefano Zampini } 62331ae86dd6SStefano Zampini } 6234cbcc2c2aSStefano Zampini 6235c8587f34SStefano Zampini /* check coarse problem residual error */ 62366e683305SStefano Zampini if (pcbddc->dbg_flag) { 62376e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 62386e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 62396e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 6240c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 62416e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 62426e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 6243779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 62446e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 62456e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 62466e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 62476e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 6248b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6249b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 6250b0f5fe93SStefano Zampini } 62516e683305SStefano Zampini if (compute_eigs) { 62526e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 6253deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 6254c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 62556e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 62566e683305SStefano 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); 62576e683305SStefano Zampini for (i=0;i<neigs;i++) { 62586e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 6259c8587f34SStefano Zampini } 62606e683305SStefano Zampini } 62616e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 62626e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 62636e683305SStefano Zampini } 6264e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 62652701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 6266c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 62676e683305SStefano Zampini if (compute_eigs) { 62686e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 62696e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 6270c8587f34SStefano Zampini } 62716e683305SStefano Zampini } 62726e683305SStefano Zampini } 6273bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 6274cbcc2c2aSStefano Zampini /* print additional info */ 6275cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 62766e683305SStefano Zampini /* waits until all processes reaches this point */ 62776e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 6278cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 6279cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6280cbcc2c2aSStefano Zampini } 6281cbcc2c2aSStefano Zampini 62822b510759SStefano Zampini /* free memory */ 6283fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 6284c8587f34SStefano Zampini PetscFunctionReturn(0); 6285c8587f34SStefano Zampini } 6286674ae819SStefano Zampini 6287f34684f1SStefano Zampini #undef __FUNCT__ 6288f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 6289f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 6290f34684f1SStefano Zampini { 6291f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6292f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 6293f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 6294dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 6295dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 629673be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 6297dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 6298f34684f1SStefano Zampini PetscErrorCode ierr; 6299f34684f1SStefano Zampini 6300f34684f1SStefano Zampini PetscFunctionBegin; 6301f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 63026c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 6303dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 63043bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 6305dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6306dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 63076583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 6308dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 6309dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 6310dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 63116c4ed002SBarry 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); 6312dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 6313dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6314dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 6315dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6316dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6317f34684f1SStefano Zampini 6318f34684f1SStefano Zampini /* check numbering */ 6319f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 6320019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 6321dc456d91SStefano Zampini PetscInt i; 6322b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 6323f34684f1SStefano Zampini 6324f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6325f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 6326f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 63271575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6328019a44ceSStefano Zampini /* counter */ 6329019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6330019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6331019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6332019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6333019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6334019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6335f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 6336f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 6337727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6338f34684f1SStefano Zampini } 6339f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6340f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6341f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6342e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6343e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6344e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6345e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6346f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6347019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6348f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6349019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 63502c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 635175c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 6352b9b85e73SStefano Zampini set_error = PETSC_TRUE; 63532c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 63542c66d082SStefano 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); 6355f34684f1SStefano Zampini } 6356f34684f1SStefano Zampini } 6357019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6358b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 6359f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6360f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6361f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 6362f34684f1SStefano Zampini } 6363f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6364f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6365e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6366e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6367f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 6368f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 6369b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 6370ca8b9ea9SStefano Zampini PetscInt *gidxs; 6371ca8b9ea9SStefano Zampini 6372ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 63733bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 6374f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 6375f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6376f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6377f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 63784bc2dc4bSStefano 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); 6379f34684f1SStefano Zampini } 6380f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6381ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 6382f34684f1SStefano Zampini } 6383f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 63841575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6385302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 6386f34684f1SStefano Zampini } 63878bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 6388f34684f1SStefano Zampini /* get back data */ 6389f34684f1SStefano Zampini *coarse_size_n = coarse_size; 6390f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 6391674ae819SStefano Zampini PetscFunctionReturn(0); 6392674ae819SStefano Zampini } 6393674ae819SStefano Zampini 6394e456f2a8SStefano Zampini #undef __FUNCT__ 6395e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 6396a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 6397e456f2a8SStefano Zampini { 6398e456f2a8SStefano Zampini IS localis_t; 6399a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 6400e456f2a8SStefano Zampini PetscScalar *vals; 6401e456f2a8SStefano Zampini PetscErrorCode ierr; 6402e456f2a8SStefano Zampini 6403e456f2a8SStefano Zampini PetscFunctionBegin; 6404a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 6405e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 6406854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 6407e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 6408e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6409a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 6410a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 64111035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 6412a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 64131035eff8SStefano Zampini } 6414a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 6415e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6416e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6417a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 6418a7dc3881SStefano Zampini /* now compute set in local ordering */ 6419a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6420a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6421a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6422a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 6423a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6424ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6425e456f2a8SStefano Zampini lsize++; 6426e456f2a8SStefano Zampini } 6427e456f2a8SStefano Zampini } 6428854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 6429a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6430ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6431e456f2a8SStefano Zampini idxs[lsize++] = i; 6432e456f2a8SStefano Zampini } 6433e456f2a8SStefano Zampini } 6434a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6435a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 6436e456f2a8SStefano Zampini *localis = localis_t; 6437e456f2a8SStefano Zampini PetscFunctionReturn(0); 6438e456f2a8SStefano Zampini } 6439906d46d4SStefano Zampini 6440b96c3477SStefano Zampini #undef __FUNCT__ 6441b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 644208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 6443b96c3477SStefano Zampini { 6444a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6445b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6446b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6447a64f4aa4SStefano Zampini Mat S_j; 6448b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6449b96c3477SStefano Zampini PetscBool free_used_adj; 6450b96c3477SStefano Zampini PetscErrorCode ierr; 6451b96c3477SStefano Zampini 6452b96c3477SStefano Zampini PetscFunctionBegin; 6453b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6454b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 645508122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6456b96c3477SStefano Zampini used_xadj = NULL; 6457b96c3477SStefano Zampini used_adjncy = NULL; 6458b96c3477SStefano Zampini } else { 645908122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 646008122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 646108122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 646208122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6463b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6464b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6465b96c3477SStefano Zampini } else { 64662fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6467b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6468b96c3477SStefano Zampini PetscInt nvtxs; 6469b96c3477SStefano Zampini 64702fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 64712fffb893SStefano Zampini if (flg_row) { 6472b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6473b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6474b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6475b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 64762fffb893SStefano Zampini } else { 64772fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 64782fffb893SStefano Zampini used_xadj = NULL; 64792fffb893SStefano Zampini used_adjncy = NULL; 64802fffb893SStefano Zampini } 64812fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6482b96c3477SStefano Zampini } 6483b96c3477SStefano Zampini } 6484d5574798SStefano Zampini 6485d5574798SStefano Zampini /* setup sub_schurs data */ 6486a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6487df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 6488df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 6489a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 649091af6908SStefano 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); 6491a64f4aa4SStefano Zampini } else { 64926816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 6493b7ab4a40SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE;; 6494a3df083aSStefano Zampini PetscInt benign_n; 649572b8c272SStefano Zampini Mat change = NULL; 64969d54b7f4SStefano Zampini Vec scaling = NULL; 649772b8c272SStefano Zampini IS change_primal = NULL; 6498a3df083aSStefano Zampini 64995feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 65005feab87aSStefano Zampini PetscInt n_vertices; 65015feab87aSStefano Zampini 65025feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 65032034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 65045feab87aSStefano Zampini } 650504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 650604708bb6SStefano Zampini if (!isseqaij) { 650704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 650804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 650904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 651004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 651104708bb6SStefano Zampini } else { 6512511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 651304708bb6SStefano Zampini } 651404708bb6SStefano Zampini } 6515a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6516a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6517ca92afb2SStefano Zampini } else { 6518a3df083aSStefano Zampini benign_n = 0; 6519ca92afb2SStefano Zampini } 6520b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 6521b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 6522b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 652372b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 652422db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 6525b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 652622db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 6527b7ab4a40SStefano Zampini } 6528b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 6529b7ab4a40SStefano 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 */ 6530b7ab4a40SStefano Zampini if (need_change) { 653188c03ad3SStefano Zampini PC_IS *pcisf; 653288c03ad3SStefano Zampini PC_BDDC *pcbddcf; 653388c03ad3SStefano Zampini PC pcf; 653488c03ad3SStefano Zampini 6535e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 653688c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 653788c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 653888c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 653988c03ad3SStefano Zampini /* hacks */ 654088c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 654172b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 654272b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 654372b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 654472b8c272SStefano Zampini pcisf->n = pcis->n; 654572b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 654688c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 654788c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 654888c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 654988c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 655088c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 655188c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 655272b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 655388c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 655488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 655572b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 655672b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 655772b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 655872b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 655972b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 656088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 656172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 656288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 656388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 656488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 656588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 656688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 656788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 656888c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 656988c03ad3SStefano Zampini } 65709d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 657191af6908SStefano 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); 657272b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 657372b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 6574ca92afb2SStefano Zampini } 6575d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6576b96c3477SStefano Zampini 6577b96c3477SStefano Zampini /* free adjacency */ 6578b96c3477SStefano Zampini if (free_used_adj) { 6579b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6580b96c3477SStefano Zampini } 6581b96c3477SStefano Zampini PetscFunctionReturn(0); 6582b96c3477SStefano Zampini } 6583b96c3477SStefano Zampini 6584b96c3477SStefano Zampini #undef __FUNCT__ 6585b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 658608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6587b96c3477SStefano Zampini { 6588b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6589b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6590b96c3477SStefano Zampini PCBDDCGraph graph; 6591b96c3477SStefano Zampini PetscErrorCode ierr; 6592b96c3477SStefano Zampini 6593b96c3477SStefano Zampini PetscFunctionBegin; 6594b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 659508122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 65963301b35fSStefano Zampini IS verticesIS,verticescomm; 65973301b35fSStefano Zampini PetscInt vsize,*idxs; 6598b96c3477SStefano Zampini 6599b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 66003301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 66013301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 66023301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 66033301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 66043301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6605b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 66067fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 6607441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 66083301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6609b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6610b96c3477SStefano Zampini } else { 6611b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6612b96c3477SStefano Zampini } 6613e4d548c7SStefano Zampini /* print some info */ 6614e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 6615e4d548c7SStefano Zampini IS vertices; 6616e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 6617e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6618e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 6619e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 6620e4d548c7SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 6621e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6622e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6623e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 6624e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 6625e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 6626e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6627e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6628e4d548c7SStefano Zampini } 6629b96c3477SStefano Zampini 6630b96c3477SStefano Zampini /* sub_schurs init */ 6631b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 6632b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 6633b334f244SStefano Zampini } 6634b334f244SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6635a64f4aa4SStefano Zampini 6636b96c3477SStefano Zampini /* free graph struct */ 663708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6638b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6639b96c3477SStefano Zampini } 6640b96c3477SStefano Zampini PetscFunctionReturn(0); 6641b96c3477SStefano Zampini } 6642fa34dd3eSStefano Zampini 6643fa34dd3eSStefano Zampini #undef __FUNCT__ 6644fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6645fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6646fa34dd3eSStefano Zampini { 6647fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6648fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6649fa34dd3eSStefano Zampini PetscErrorCode ierr; 6650fa34dd3eSStefano Zampini 6651fa34dd3eSStefano Zampini PetscFunctionBegin; 6652fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6653fa34dd3eSStefano Zampini IS zerodiag = NULL; 66544f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6655fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 66564f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 665775c01103SStefano Zampini PetscReal norm; 6658fa34dd3eSStefano Zampini PetscInt i; 6659fa34dd3eSStefano Zampini 6660fa34dd3eSStefano Zampini /* B0 and B0_B */ 6661fa34dd3eSStefano Zampini if (zerodiag) { 6662fa34dd3eSStefano Zampini IS dummy; 6663fa34dd3eSStefano Zampini 66644f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 66654f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6666fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6667fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6668fa34dd3eSStefano Zampini } 6669fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6670fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6671fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6672fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6673fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6674fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6675fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6676fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6677fa34dd3eSStefano Zampini /* S_j */ 6678fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6679fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6680fa34dd3eSStefano Zampini 6681fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6682fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6683fa34dd3eSStefano Zampini /* continuous in primal space */ 6684fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6685fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6686fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6687fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 66884f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 66894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6690fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6691fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6692fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6693fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6694fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6695fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6696fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6697fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6698fa34dd3eSStefano Zampini 6699fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6700fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6701fa34dd3eSStefano Zampini /* local with Schur */ 6702fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6703fa34dd3eSStefano Zampini if (zerodiag) { 6704fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 67054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6706fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6707fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6708fa34dd3eSStefano Zampini } 6709fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6710fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6711fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6712fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6713fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6714fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6715fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6716fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6717fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6718fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6719fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6720fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6721fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6722fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6723fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6724fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6725fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6726fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6727fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6728fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6729fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6730fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6731fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6732fa34dd3eSStefano Zampini if (zerodiag) { 6733fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6734fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 67354f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6736fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6737fa34dd3eSStefano Zampini } 6738fa34dd3eSStefano Zampini /* BDDC */ 6739fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6740fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6741fa34dd3eSStefano Zampini 6742fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6743fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6744fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6745fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 67464f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 67474f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6748fa34dd3eSStefano Zampini } 67494f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6750fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6751fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6752fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6753fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6754fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6755fa34dd3eSStefano Zampini } 6756fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6757fa34dd3eSStefano Zampini } 6758