11cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4674ae819SStefano Zampini #include <petscblaslapack.h> 5daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 6674ae819SStefano Zampini 7669cc0f4SStefano Zampini 8669cc0f4SStefano Zampini #undef __FUNCT__ 9669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 10669cc0f4SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PCBDDCGraph graph, MatNullSpace *nnsp) 11669cc0f4SStefano Zampini { 12*a198735bSStefano Zampini Mat loc_divudotp; 13*a198735bSStefano Zampini Vec p,v,quad_vec,*quad_vecs; 14669cc0f4SStefano Zampini ISLocalToGlobalMapping rmap; 15669cc0f4SStefano Zampini IS *faces,*edges; 16669cc0f4SStefano Zampini PetscScalar *vals; 17669cc0f4SStefano Zampini const PetscScalar *array; 18669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 191ae86dd6SStefano Zampini PetscMPIInt rank; 20*a198735bSStefano Zampini PetscErrorCode ierr; 21669cc0f4SStefano Zampini 22669cc0f4SStefano Zampini PetscFunctionBegin; 23669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 24669cc0f4SStefano Zampini if (graph->twodim) { 25669cc0f4SStefano Zampini lmaxneighs = 2; 26669cc0f4SStefano Zampini } else { 27669cc0f4SStefano Zampini lmaxneighs = 1; 28669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 29669cc0f4SStefano Zampini const PetscInt *idxs; 30669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 31669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 32669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 33669cc0f4SStefano Zampini } 34669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 35669cc0f4SStefano Zampini } 36669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 37669cc0f4SStefano Zampini maxsize = 0; 38669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 39669cc0f4SStefano Zampini PetscInt nn; 40669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 41669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 42669cc0f4SStefano Zampini } 43669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 44669cc0f4SStefano Zampini PetscInt nn; 45669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 46669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 47669cc0f4SStefano Zampini } 48669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 49669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 50669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 51669cc0f4SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rmap,NULL);CHKERRQ(ierr); 52669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 531ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 54669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 55669cc0f4SStefano Zampini PetscInt first,last; 56669cc0f4SStefano Zampini 57669cc0f4SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],rmap);CHKERRQ(ierr); 58669cc0f4SStefano Zampini /* the near-null space fo BDDC carries information on quadrature weights, 59669cc0f4SStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 60669cc0f4SStefano Zampini and create a suitable set of basis vectors first */ 61669cc0f4SStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 62669cc0f4SStefano Zampini if (i>=first && i < last) { 63669cc0f4SStefano Zampini PetscScalar *data; 64669cc0f4SStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 65669cc0f4SStefano Zampini data[i-first] = 1.; 66669cc0f4SStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 67669cc0f4SStefano Zampini } 68669cc0f4SStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 69669cc0f4SStefano Zampini } 70669cc0f4SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 711ae86dd6SStefano Zampini for (i=0;i<maxneighs;i++) { /* reset vectors */ 721ae86dd6SStefano Zampini PetscInt first,last; 731ae86dd6SStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 741ae86dd6SStefano Zampini if (i>=first && i < last) { 751ae86dd6SStefano Zampini PetscScalar *data; 761ae86dd6SStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 771ae86dd6SStefano Zampini data[i-first] = 0.; 781ae86dd6SStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 791ae86dd6SStefano Zampini } 801ae86dd6SStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 811ae86dd6SStefano Zampini } 82669cc0f4SStefano Zampini /* compute local quad vec */ 83*a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 84*a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 85669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 86*a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 87669cc0f4SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 88669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 891ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 901ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 91669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 92669cc0f4SStefano Zampini const PetscInt *idxs; 93669cc0f4SStefano Zampini PetscInt idx,nn,j; 94669cc0f4SStefano Zampini 95669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 96669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 97669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 981ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 99669cc0f4SStefano Zampini idx = -(idx+1); 100669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 101669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 102669cc0f4SStefano Zampini ierr = ISDestroy(&faces[i]);CHKERRQ(ierr); 103669cc0f4SStefano Zampini } 104669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 105669cc0f4SStefano Zampini const PetscInt *idxs; 106669cc0f4SStefano Zampini PetscInt idx,nn,j; 107669cc0f4SStefano Zampini 108669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 109669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 110669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 1111ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 112669cc0f4SStefano Zampini idx = -(idx+1); 113669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 114669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 115669cc0f4SStefano Zampini ierr = ISDestroy(&edges[i]);CHKERRQ(ierr); 116669cc0f4SStefano Zampini } 117669cc0f4SStefano Zampini ierr = PetscFree(edges);CHKERRQ(ierr); 118669cc0f4SStefano Zampini ierr = PetscFree(faces);CHKERRQ(ierr); 119669cc0f4SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 120669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 121669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 122669cc0f4SStefano Zampini 123669cc0f4SStefano Zampini /* assemble near null space */ 124669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 125669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 126669cc0f4SStefano Zampini } 127669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 128669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 129669cc0f4SStefano Zampini } 130669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 131669cc0f4SStefano Zampini PetscFunctionReturn(0); 132669cc0f4SStefano Zampini } 133669cc0f4SStefano Zampini 134669cc0f4SStefano Zampini 135a3df083aSStefano Zampini #undef __FUNCT__ 1361f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 1371f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 1381f4df5f7SStefano Zampini { 1391f4df5f7SStefano Zampini PetscErrorCode ierr; 1401f4df5f7SStefano Zampini Vec local,global; 1411f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1421f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1431f4df5f7SStefano Zampini 1441f4df5f7SStefano Zampini PetscFunctionBegin; 1451f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 1461f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 1471f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 1481f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 1491f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 1501f4df5f7SStefano Zampini PetscInt i; 1511f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1521f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 1531f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 1541f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 1551f4df5f7SStefano Zampini } 1561f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 1571f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 1581f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 1591f4df5f7SStefano Zampini } 1601f4df5f7SStefano Zampini } else { 161986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 1621f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 163986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 164986cdee1SStefano Zampini if (i > 1) { 165986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 1661f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1671f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 1681f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 1691f4df5f7SStefano Zampini } 1701f4df5f7SStefano Zampini } 1711f4df5f7SStefano Zampini } 172986cdee1SStefano Zampini } 1731f4df5f7SStefano Zampini 1741f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 1751f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 1761f4df5f7SStefano Zampini } 1771f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 1781f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1791f4df5f7SStefano Zampini } 1801f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 1811f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1821f4df5f7SStefano Zampini } 1831f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 1841f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 1851f4df5f7SStefano Zampini PetscFunctionReturn(0); 1861f4df5f7SStefano Zampini } 1871f4df5f7SStefano Zampini 1881f4df5f7SStefano Zampini #undef __FUNCT__ 1893e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 1903e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 1913e589ea0SStefano Zampini { 1923e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 1933e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1943e589ea0SStefano Zampini PetscErrorCode ierr; 1953e589ea0SStefano Zampini 1963e589ea0SStefano Zampini PetscFunctionBegin; 1973e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 1983e589ea0SStefano Zampini PetscFunctionReturn(0); 1993e589ea0SStefano Zampini } 2003e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2013e589ea0SStefano Zampini Vec swap; 2023e589ea0SStefano Zampini 2033e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 2043e589ea0SStefano Zampini swap = pcbddc->work_change; 2053e589ea0SStefano Zampini pcbddc->work_change = r; 2063e589ea0SStefano Zampini r = swap; 2073e589ea0SStefano Zampini } 2083e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2093e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2103e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 2113e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 2123e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2133e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2143e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2153e589ea0SStefano Zampini Vec swap; 2163e589ea0SStefano Zampini 2173e589ea0SStefano Zampini swap = r; 2183e589ea0SStefano Zampini r = pcbddc->work_change; 2193e589ea0SStefano Zampini pcbddc->work_change = swap; 2203e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 2213e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 2223e589ea0SStefano Zampini } 2233e589ea0SStefano Zampini PetscFunctionReturn(0); 2243e589ea0SStefano Zampini } 2253e589ea0SStefano Zampini 2263e589ea0SStefano Zampini #undef __FUNCT__ 227a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 228a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 229a3df083aSStefano Zampini { 230a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 231a3df083aSStefano Zampini PetscErrorCode ierr; 232a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 233a3df083aSStefano Zampini 234a3df083aSStefano Zampini PetscFunctionBegin; 235a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 236a3df083aSStefano Zampini if (transpose) { 237a3df083aSStefano Zampini apply_right = ctx->apply_left; 238a3df083aSStefano Zampini apply_left = ctx->apply_right; 239a3df083aSStefano Zampini } else { 240a3df083aSStefano Zampini apply_right = ctx->apply_right; 241a3df083aSStefano Zampini apply_left = ctx->apply_left; 242a3df083aSStefano Zampini } 243a3df083aSStefano Zampini reset_x = PETSC_FALSE; 244a3df083aSStefano Zampini if (apply_right) { 245a3df083aSStefano Zampini const PetscScalar *ax; 246a3df083aSStefano Zampini PetscInt nl,i; 247a3df083aSStefano Zampini 248a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 249a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 250a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 251a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 252a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 253a3df083aSStefano Zampini PetscScalar sum,val; 254a3df083aSStefano Zampini const PetscInt *idxs; 255a3df083aSStefano Zampini PetscInt nz,j; 256a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 257a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 258a3df083aSStefano Zampini sum = 0.; 259a3df083aSStefano Zampini if (ctx->apply_p0) { 260a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 261a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 262a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 263a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 264a3df083aSStefano Zampini } 265a3df083aSStefano Zampini } else { 266a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 267a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 268a3df083aSStefano Zampini } 269a3df083aSStefano Zampini } 270a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 271a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 272a3df083aSStefano Zampini } 273a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 274a3df083aSStefano Zampini reset_x = PETSC_TRUE; 275a3df083aSStefano Zampini } 276a3df083aSStefano Zampini if (transpose) { 277a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 278a3df083aSStefano Zampini } else { 279a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 280a3df083aSStefano Zampini } 281a3df083aSStefano Zampini if (reset_x) { 282a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 283a3df083aSStefano Zampini } 284a3df083aSStefano Zampini if (apply_left) { 285a3df083aSStefano Zampini PetscScalar *ay; 286a3df083aSStefano Zampini PetscInt i; 287a3df083aSStefano Zampini 288a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 289a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 290a3df083aSStefano Zampini PetscScalar sum,val; 291a3df083aSStefano Zampini const PetscInt *idxs; 292a3df083aSStefano Zampini PetscInt nz,j; 293a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 294a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 295a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 296a3df083aSStefano Zampini if (ctx->apply_p0) { 297a3df083aSStefano Zampini sum = 0.; 298a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 299a3df083aSStefano Zampini sum += ay[idxs[j]]; 300a3df083aSStefano Zampini ay[idxs[j]] += val; 301a3df083aSStefano Zampini } 302a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 303a3df083aSStefano Zampini } else { 304a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 305a3df083aSStefano Zampini ay[idxs[j]] += val; 306a3df083aSStefano Zampini } 307a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 308a3df083aSStefano Zampini } 309a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 310a3df083aSStefano Zampini } 311a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 312a3df083aSStefano Zampini } 313a3df083aSStefano Zampini PetscFunctionReturn(0); 314a3df083aSStefano Zampini } 315a3df083aSStefano Zampini 316a3df083aSStefano Zampini #undef __FUNCT__ 317a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 318a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 319a3df083aSStefano Zampini { 320a3df083aSStefano Zampini PetscErrorCode ierr; 321a3df083aSStefano Zampini 322a3df083aSStefano Zampini PetscFunctionBegin; 323a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 324a3df083aSStefano Zampini PetscFunctionReturn(0); 325a3df083aSStefano Zampini } 326a3df083aSStefano Zampini 327a3df083aSStefano Zampini #undef __FUNCT__ 328a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 329a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 330a3df083aSStefano Zampini { 331a3df083aSStefano Zampini PetscErrorCode ierr; 332a3df083aSStefano Zampini 333a3df083aSStefano Zampini PetscFunctionBegin; 334a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 335a3df083aSStefano Zampini PetscFunctionReturn(0); 336a3df083aSStefano Zampini } 337a3df083aSStefano Zampini 338a3df083aSStefano Zampini #undef __FUNCT__ 339a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 340a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 341a3df083aSStefano Zampini { 342a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 343a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 344a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 345a3df083aSStefano Zampini PetscErrorCode ierr; 346a3df083aSStefano Zampini 347a3df083aSStefano Zampini PetscFunctionBegin; 348a3df083aSStefano Zampini if (!restore) { 3491dd7afcfSStefano Zampini Mat A_IB,A_BI; 350a3df083aSStefano Zampini PetscScalar *work; 351b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 352a3df083aSStefano Zampini 3531dd7afcfSStefano Zampini if (pcbddc->benign_original_mat) { 3541dd7afcfSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 3551dd7afcfSStefano Zampini } 3561dd7afcfSStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) { 3571dd7afcfSStefano Zampini PetscFunctionReturn(0); 3581dd7afcfSStefano Zampini } 359a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 360a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 361a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 362a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 363a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 364a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 365a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 366a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 367a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 368a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 369a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 370a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 371059032f7SStefano Zampini if (reuse) { 372a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 3731dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 374059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 375059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 376059032f7SStefano Zampini PetscInt i; 377059032f7SStefano Zampini 378059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 379059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 380059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 381059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 382059032f7SStefano Zampini } 383059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 3841dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 385059032f7SStefano Zampini } 386a3df083aSStefano Zampini ctx->A = pcis->A_IB; 387a3df083aSStefano Zampini ctx->work = work; 388a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 389a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 390a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 391a3df083aSStefano Zampini pcis->A_IB = A_IB; 392a3df083aSStefano Zampini 393a3df083aSStefano Zampini /* A_BI as A_IB^T */ 394a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 395a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 396a3df083aSStefano Zampini pcis->A_BI = A_BI; 397a3df083aSStefano Zampini } else { 3981dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 3991dd7afcfSStefano Zampini PetscFunctionReturn(0); 4001dd7afcfSStefano Zampini } 401a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 402a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 403a3df083aSStefano Zampini pcis->A_IB = ctx->A; 4041dd7afcfSStefano Zampini ctx->A = NULL; 4051dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 4061dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 4071dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 4081dd7afcfSStefano Zampini if (ctx->free) { 409059032f7SStefano Zampini PetscInt i; 4101dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 411059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 412059032f7SStefano Zampini } 413059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 414059032f7SStefano Zampini } 415a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 416a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 417a3df083aSStefano Zampini } 418a3df083aSStefano Zampini PetscFunctionReturn(0); 419a3df083aSStefano Zampini } 420a3df083aSStefano Zampini 421a3df083aSStefano Zampini /* used just in bddc debug mode */ 422a3df083aSStefano Zampini #undef __FUNCT__ 423a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 424a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 425a3df083aSStefano Zampini { 426a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 427a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 428a3df083aSStefano Zampini Mat An; 429a3df083aSStefano Zampini PetscErrorCode ierr; 430a3df083aSStefano Zampini 431a3df083aSStefano Zampini PetscFunctionBegin; 432a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 433a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 434a3df083aSStefano Zampini if (is1) { 435a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 436a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 437a3df083aSStefano Zampini } else { 438a3df083aSStefano Zampini *B = An; 439a3df083aSStefano Zampini } 440a3df083aSStefano Zampini PetscFunctionReturn(0); 441a3df083aSStefano Zampini } 442a3df083aSStefano Zampini 4431cf9b237SStefano Zampini /* TODO: add reuse flag */ 4441cf9b237SStefano Zampini #undef __FUNCT__ 4451cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 4461cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 4471cf9b237SStefano Zampini { 4481cf9b237SStefano Zampini Mat Bt; 4491cf9b237SStefano Zampini PetscScalar *a,*bdata; 4501cf9b237SStefano Zampini const PetscInt *ii,*ij; 4511cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 4521cf9b237SStefano Zampini PetscBool flg_row; 4531cf9b237SStefano Zampini PetscErrorCode ierr; 4541cf9b237SStefano Zampini 4551cf9b237SStefano Zampini PetscFunctionBegin; 4561cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 4571cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 4581cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 4591cf9b237SStefano Zampini nnz = n; 4601cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 4611cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 4621cf9b237SStefano Zampini } 4631cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 4641cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 4651cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 4661cf9b237SStefano Zampini nnz = 0; 4671cf9b237SStefano Zampini bii[0] = 0; 4681cf9b237SStefano Zampini for (i=0;i<n;i++) { 4691cf9b237SStefano Zampini PetscInt j; 4701cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 4711cf9b237SStefano Zampini PetscScalar entry = a[j]; 4721cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 4731cf9b237SStefano Zampini bij[nnz] = ij[j]; 4741cf9b237SStefano Zampini bdata[nnz] = entry; 4751cf9b237SStefano Zampini nnz++; 4761cf9b237SStefano Zampini } 4771cf9b237SStefano Zampini } 4781cf9b237SStefano Zampini bii[i+1] = nnz; 4791cf9b237SStefano Zampini } 4801cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 4811cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 4821cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 4831cf9b237SStefano Zampini { 4841cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 4851cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 4861cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 4871cf9b237SStefano Zampini } 4881cf9b237SStefano Zampini *B = Bt; 4891cf9b237SStefano Zampini PetscFunctionReturn(0); 4901cf9b237SStefano Zampini } 4911cf9b237SStefano Zampini 492674ae819SStefano Zampini #undef __FUNCT__ 4934f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 4944f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 4954f1b2e48SStefano Zampini { 4964f1b2e48SStefano Zampini Mat B; 4974f1b2e48SStefano Zampini IS is_dummy,*cc_n; 4984f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 4994f1b2e48SStefano Zampini PCBDDCGraph graph; 5004f1b2e48SStefano Zampini PetscInt i,n; 5014f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 5024f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 5034f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 5044f1b2e48SStefano Zampini PetscErrorCode ierr; 5054f1b2e48SStefano Zampini 5064f1b2e48SStefano Zampini PetscFunctionBegin; 50763c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 50863c961adSStefano Zampini *ncc = 0; 50963c961adSStefano Zampini *cc = NULL; 51063c961adSStefano Zampini PetscFunctionReturn(0); 51163c961adSStefano Zampini } 5124f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 5134f1b2e48SStefano Zampini if (!isseqaij && filter) { 5141cf9b237SStefano Zampini PetscBool isseqdense; 5151cf9b237SStefano Zampini 5161cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 5171cf9b237SStefano Zampini if (!isseqdense) { 5184f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 5191cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 5201cf9b237SStefano Zampini PetscScalar *array; 5211cf9b237SStefano Zampini PetscReal chop=1.e-6; 5221cf9b237SStefano Zampini 5231cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 5241cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 5251cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 5261cf9b237SStefano Zampini for (i=0;i<n;i++) { 5271cf9b237SStefano Zampini PetscInt j; 5281cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 5291cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 5301cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 5311cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 5321cf9b237SStefano Zampini } 5331cf9b237SStefano Zampini } 5341cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 5359d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 5361cf9b237SStefano Zampini } 5374f1b2e48SStefano Zampini } else { 5384f1b2e48SStefano Zampini B = A; 5394f1b2e48SStefano Zampini } 5404f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5414f1b2e48SStefano Zampini 5424f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 5434f1b2e48SStefano Zampini if (filter) { 5444f1b2e48SStefano Zampini PetscScalar *data; 5454f1b2e48SStefano Zampini PetscInt j,cum; 5464f1b2e48SStefano Zampini 5474f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 5484f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 5494f1b2e48SStefano Zampini cum = 0; 5504f1b2e48SStefano Zampini for (i=0;i<n;i++) { 5514f1b2e48SStefano Zampini PetscInt t; 5524f1b2e48SStefano Zampini 5534f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 5544f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 5554f1b2e48SStefano Zampini continue; 5564f1b2e48SStefano Zampini } 5574f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 5584f1b2e48SStefano Zampini } 5594f1b2e48SStefano Zampini t = xadj_filtered[i]; 5604f1b2e48SStefano Zampini xadj_filtered[i] = cum; 5614f1b2e48SStefano Zampini cum += t; 5624f1b2e48SStefano Zampini } 5634f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 5644f1b2e48SStefano Zampini } else { 5654f1b2e48SStefano Zampini xadj_filtered = NULL; 5664f1b2e48SStefano Zampini adjncy_filtered = NULL; 5674f1b2e48SStefano Zampini } 5684f1b2e48SStefano Zampini 5694f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 5704f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 5714f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 5724f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 5734f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 5744f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 5754f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 5764f1b2e48SStefano Zampini if (xadj_filtered) { 5774f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 5784f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 5794f1b2e48SStefano Zampini } else { 5804f1b2e48SStefano Zampini graph->xadj = xadj; 5814f1b2e48SStefano Zampini graph->adjncy = adjncy; 5824f1b2e48SStefano Zampini } 5834f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 5844f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5854f1b2e48SStefano Zampini /* partial clean up */ 5864f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 5874f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5881cf9b237SStefano Zampini if (A != B) { 5894f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 5904f1b2e48SStefano Zampini } 5914f1b2e48SStefano Zampini 5924f1b2e48SStefano Zampini /* get back data */ 5931cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 5941cf9b237SStefano Zampini if (cc) { 5954f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 5964f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 5974f1b2e48SStefano 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); 5984f1b2e48SStefano Zampini } 5994f1b2e48SStefano Zampini *cc = cc_n; 6001cf9b237SStefano Zampini } 6014f1b2e48SStefano Zampini /* clean up graph */ 6024f1b2e48SStefano Zampini graph->xadj = 0; 6034f1b2e48SStefano Zampini graph->adjncy = 0; 6044f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6054f1b2e48SStefano Zampini PetscFunctionReturn(0); 6064f1b2e48SStefano Zampini } 6074f1b2e48SStefano Zampini 6084f1b2e48SStefano Zampini #undef __FUNCT__ 6095408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 6105408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 6115408967cSStefano Zampini { 6125408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6135408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 614dee84bffSStefano Zampini IS dirIS = NULL; 6154f1b2e48SStefano Zampini PetscInt i; 6165408967cSStefano Zampini PetscErrorCode ierr; 6175408967cSStefano Zampini 6185408967cSStefano Zampini PetscFunctionBegin; 619dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 6205408967cSStefano Zampini if (zerodiag) { 6215408967cSStefano Zampini Mat A; 6225408967cSStefano Zampini Vec vec3_N; 6235408967cSStefano Zampini PetscScalar *vals; 6245408967cSStefano Zampini const PetscInt *idxs; 625d12d3064SStefano Zampini PetscInt nz,*count; 6265408967cSStefano Zampini 6275408967cSStefano Zampini /* p0 */ 6285408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 6295408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 6305408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 6315408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 6324f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 6335408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6345408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6355408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6365408967cSStefano Zampini /* v_I */ 6375408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 6385408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 6395408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6405408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 6415408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 6425408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 6435408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6445408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 6455408967cSStefano Zampini if (dirIS) { 6465408967cSStefano Zampini PetscInt n; 6475408967cSStefano Zampini 6485408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 6495408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 6505408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 6515408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 6525408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 6535408967cSStefano Zampini } 6545408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 6555408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 6565408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 6575408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 658669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 6595408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 6605408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 661fbfcb133SStefano Zampini if (PetscAbsScalar(vals[0]) > 1.e-1) { 662b9b0e38cSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! b(v_I,p_0) = %1.6e (should be numerically 0.)",PetscAbsScalar(vals[0])); 6635408967cSStefano Zampini } 6645408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6655408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 666d12d3064SStefano Zampini 667d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 668d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 669d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 670d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 671d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 672d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 673d4d8cf7bSStefano Zampini for (i=0;i<nz;i++) { 674d12d3064SStefano Zampini if (count[idxs[i]]) { 675d12d3064SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 676d12d3064SStefano Zampini } 677d4d8cf7bSStefano Zampini } 678d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 679d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 6805408967cSStefano Zampini } 681dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 6825408967cSStefano Zampini 6835408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 6845408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 6854f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 6865408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 6874f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 6885408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 6894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6904f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 6914f1b2e48SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %1.4e at %d instead of %1.4e\n",pcbddc->benign_p0[i],i,-PetscGlobalRank-i);CHKERRQ(ierr); 6924f1b2e48SStefano Zampini } 6935408967cSStefano Zampini } 6945408967cSStefano Zampini PetscFunctionReturn(0); 6955408967cSStefano Zampini } 6965408967cSStefano Zampini 6975408967cSStefano Zampini #undef __FUNCT__ 698339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 699339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 700339f8db1SStefano Zampini { 701339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7024f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 703b0f5fe93SStefano Zampini PetscInt nz,n; 7041f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 7054f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 706339f8db1SStefano Zampini PetscErrorCode ierr; 707339f8db1SStefano Zampini 708339f8db1SStefano Zampini PetscFunctionBegin; 7099f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 7109f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 711a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 712a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 713a3df083aSStefano Zampini } 714a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 715a3df083aSStefano Zampini pcbddc->benign_n = 0; 7161ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 7174f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 7184f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 7194f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 7201ae86dd6SStefano Zampini since the local Schur complements are already SPD 7214f1b2e48SStefano Zampini */ 7224f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 7234f1b2e48SStefano Zampini have_null = PETSC_TRUE; 72440fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 7254f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 7264f1b2e48SStefano Zampini 7274f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 7284f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 7294f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 7304f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 731ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 73240fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 73340fa8d13SStefano Zampini if (!sorted) { 73440fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 73540fa8d13SStefano Zampini } 73640fa8d13SStefano Zampini } else { 73740fa8d13SStefano Zampini pressures = NULL; 73840fa8d13SStefano Zampini } 73997d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 74097d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 74127b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 74297d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 743339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 744339f8db1SStefano Zampini if (!sorted) { 745339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 746339f8db1SStefano Zampini } 747339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 7484f1b2e48SStefano Zampini if (!nz) { 7494f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 7504f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 75140fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 75240fa8d13SStefano Zampini } 7534f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 7544f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 7554f1b2e48SStefano Zampini zerodiag_subs = NULL; 7564f1b2e48SStefano Zampini pcbddc->benign_n = 0; 7571f4df5f7SStefano Zampini n_interior_dofs = 0; 7581f4df5f7SStefano Zampini interior_dofs = NULL; 7591f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 7601f4df5f7SStefano Zampini PetscInt n,i,j; 7611f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 7621f4df5f7SStefano Zampini PetscInt *iwork; 7631f4df5f7SStefano Zampini 7641f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 7651f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 7661f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 7671f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 7681f4df5f7SStefano Zampini for (i=0;i<n_neigh;i++) 7691f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 7701f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 7711f4df5f7SStefano Zampini for (i=0;i<n;i++) 7721f4df5f7SStefano Zampini if (!iwork[i]) 7731f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 7741f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 7751f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 7761f4df5f7SStefano Zampini } 7774f1b2e48SStefano Zampini if (has_null_pressures) { 7784f1b2e48SStefano Zampini IS *subs; 7791f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 7801f4df5f7SStefano Zampini const PetscInt *idxs; 7811f4df5f7SStefano Zampini PetscScalar *array; 7821f4df5f7SStefano Zampini Vec *work; 7831f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 7844f1b2e48SStefano Zampini 7854f1b2e48SStefano Zampini subs = pcbddc->local_subs; 7864f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 7871f4df5f7SStefano 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) */ 7881f4df5f7SStefano Zampini if (pcbddc->current_level) { 7891f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 7901f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 7911f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 7921f4df5f7SStefano Zampini /* work[0] = 1_p */ 7931f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 7941f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 7951f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 7961f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 7971f4df5f7SStefano Zampini /* work[0] = 1_v */ 7981f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 7991f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 8001f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 8011f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 8021f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 8031f4df5f7SStefano Zampini } 8044f1b2e48SStefano Zampini if (nsubs > 1) { 8054f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 8064f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 8074f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 8084f1b2e48SStefano Zampini IS t_zerodiag_subs; 8094f1b2e48SStefano Zampini PetscInt nl; 8104f1b2e48SStefano Zampini 8114f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 8124f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 8134f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 8144f1b2e48SStefano Zampini if (nl) { 8154f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 8164f1b2e48SStefano Zampini 8171f4df5f7SStefano Zampini if (pcbddc->current_level) { 8181f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 8191f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 8201f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 8211f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 8221f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 8231f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 8241f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 8251f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 8261f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 8271f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 8281f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 8291f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 8301f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 8311f4df5f7SStefano Zampini valid = PETSC_FALSE; 8321f4df5f7SStefano Zampini break; 8331f4df5f7SStefano Zampini } 8341f4df5f7SStefano Zampini } 8351f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 8361f4df5f7SStefano Zampini } 8371f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 8381f4df5f7SStefano Zampini IS t_bc; 8391f4df5f7SStefano Zampini PetscInt nzb; 8401f4df5f7SStefano Zampini 8411f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 8421f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 8431f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 8441f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 8451f4df5f7SStefano Zampini } 8461f4df5f7SStefano Zampini if (valid && pressures) { 8474f1b2e48SStefano Zampini IS t_pressure_subs; 8484f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 8494f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 8504f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 8514f1b2e48SStefano Zampini } 8524f1b2e48SStefano Zampini if (valid) { 8534f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 8544f1b2e48SStefano Zampini pcbddc->benign_n++; 8554f1b2e48SStefano Zampini } else { 8564f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 8574f1b2e48SStefano Zampini } 8584f1b2e48SStefano Zampini } 8594f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 8604f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 8614f1b2e48SStefano Zampini } 8624f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 8634f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 8641f4df5f7SStefano Zampini 8651f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 8661f4df5f7SStefano Zampini PetscInt nzb; 8671f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 8681f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 8691f4df5f7SStefano Zampini } 8701f4df5f7SStefano Zampini if (valid && pressures) { 8714f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 8724f1b2e48SStefano Zampini } 8731f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 8741f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 8751f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 8761f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 8771f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 8781f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 8791f4df5f7SStefano Zampini valid = PETSC_FALSE; 8801f4df5f7SStefano Zampini break; 8811f4df5f7SStefano Zampini } 8821f4df5f7SStefano Zampini } 8831f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 8841f4df5f7SStefano Zampini } 8854f1b2e48SStefano Zampini if (valid) { 8864f1b2e48SStefano Zampini pcbddc->benign_n = 1; 887ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 8884f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 8894f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 8904f1b2e48SStefano Zampini } 8914f1b2e48SStefano Zampini } 8921f4df5f7SStefano Zampini if (pcbddc->current_level) { 8931f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 8944f1b2e48SStefano Zampini } 8951f4df5f7SStefano Zampini } 8961f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 8974f1b2e48SStefano Zampini 8984f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 899b9b0e38cSStefano Zampini PetscInt n; 900b9b0e38cSStefano Zampini 9014f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 9024f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 903b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 904b9b0e38cSStefano Zampini if (n) { 9054f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 9064f1b2e48SStefano Zampini have_null = PETSC_FALSE; 9074f1b2e48SStefano Zampini } 908b9b0e38cSStefano Zampini } 9094f1b2e48SStefano Zampini 9104f1b2e48SStefano Zampini /* final check for null pressures */ 9114f1b2e48SStefano Zampini if (zerodiag && pressures) { 9124f1b2e48SStefano Zampini PetscInt nz,np; 9134f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 9144f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 9154f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 9164f1b2e48SStefano Zampini } 9174f1b2e48SStefano Zampini 9184f1b2e48SStefano Zampini if (recompute_zerodiag) { 9194f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 9204f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 9214f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 9224f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 9234f1b2e48SStefano Zampini } else { 9244f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 9254f1b2e48SStefano Zampini 9264f1b2e48SStefano Zampini nzn = 0; 9274f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 9284f1b2e48SStefano Zampini PetscInt ns; 9294f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 9304f1b2e48SStefano Zampini nzn += ns; 9314f1b2e48SStefano Zampini } 9324f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 9334f1b2e48SStefano Zampini nzn = 0; 9344f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 9354f1b2e48SStefano Zampini PetscInt ns,*idxs; 9364f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 9374f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 9384f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 9394f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 9404f1b2e48SStefano Zampini nzn += ns; 9414f1b2e48SStefano Zampini } 9424f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 9434f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 9444f1b2e48SStefano Zampini } 9454f1b2e48SStefano Zampini have_null = PETSC_FALSE; 9464f1b2e48SStefano Zampini } 9474f1b2e48SStefano Zampini 948669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 949*a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 950*a198735bSStefano Zampini Mat A,loc_divudotp; 951*a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 952*a198735bSStefano Zampini IS row,col,isused = NULL; 953*a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 954*a198735bSStefano Zampini 9551f4df5f7SStefano Zampini if (pressures) { 9561f4df5f7SStefano Zampini isused = pressures; 9571f4df5f7SStefano Zampini } else { 9581f4df5f7SStefano Zampini isused = zerodiag; 9591f4df5f7SStefano Zampini } 960*a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 961669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 9621ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 9631ae86dd6SStefano 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"); 964*a198735bSStefano Zampini n_isused = 0; 965*a198735bSStefano Zampini if (isused) { 966*a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 967*a198735bSStefano Zampini } 968*a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 969*a198735bSStefano Zampini st = st-n_isused; 9701ae86dd6SStefano Zampini if (n) { 971*a198735bSStefano Zampini const PetscInt *gidxs; 972*a198735bSStefano Zampini 973*a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 974*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 975*a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 976*a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 977*a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 978*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 9791ae86dd6SStefano Zampini } else { 980*a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 981*a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 982*a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 983*a198735bSStefano Zampini } 984*a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 985*a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 986*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 987*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 988*a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 989*a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 990*a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 991*a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 992*a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 993*a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 994*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 995*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 996*a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 997*a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 9981ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9991ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10001ae86dd6SStefano Zampini } 1001b3afcdbeSStefano Zampini 1002b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 10034f1b2e48SStefano Zampini if (has_null_pressures) { 10044f1b2e48SStefano Zampini IS zerodiagc; 10054f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 10064f1b2e48SStefano Zampini PetscInt i,s,*nnz; 10074f1b2e48SStefano Zampini 10084f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 1009339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 1010339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 1011339f8db1SStefano Zampini /* local change of basis for pressures */ 1012339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 101397d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 1014339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 1015339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1016339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 10174f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 10184f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 10194f1b2e48SStefano Zampini PetscInt nzs,j; 10204f1b2e48SStefano Zampini 10214f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 10224f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 10234f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 10244f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 10254f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 10264f1b2e48SStefano Zampini } 1027339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 1028339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1029339f8db1SStefano Zampini /* set identity on velocities */ 1030339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 1031339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 1032339f8db1SStefano Zampini } 10334f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 10344f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 10359f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 10364f1b2e48SStefano 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); 1037339f8db1SStefano Zampini /* set change on pressures */ 10384f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 10394f1b2e48SStefano Zampini PetscScalar *array; 10404f1b2e48SStefano Zampini PetscInt nzs; 10414f1b2e48SStefano Zampini 10424f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 10434f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 10444f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 1045339f8db1SStefano Zampini PetscScalar vals[2]; 1046339f8db1SStefano Zampini PetscInt cols[2]; 1047339f8db1SStefano Zampini 1048339f8db1SStefano Zampini cols[0] = idxs[i]; 10494f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 1050339f8db1SStefano Zampini vals[0] = 1.; 1051b0f5fe93SStefano Zampini vals[1] = 1.; 10524f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 1053339f8db1SStefano Zampini } 10544f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 10554f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 10564f1b2e48SStefano Zampini array[nzs-1] = 1.; 10574f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 10584f1b2e48SStefano Zampini /* store local idxs for p0 */ 10594f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 10604f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 1061339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 10624f1b2e48SStefano Zampini } 1063339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1064339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1065a3df083aSStefano Zampini /* project if needed */ 1066a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 10671dd7afcfSStefano Zampini Mat M; 10681dd7afcfSStefano Zampini 10691dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 1070339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 10711dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 10721dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1073a3df083aSStefano Zampini } 10744f1b2e48SStefano Zampini /* store global idxs for p0 */ 10754f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1076339f8db1SStefano Zampini } 1077ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 10784f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 1079b0f5fe93SStefano Zampini 1080b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 1081b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 108227b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 108327b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1084339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 1085339f8db1SStefano Zampini PetscFunctionReturn(0); 1086339f8db1SStefano Zampini } 1087339f8db1SStefano Zampini 1088339f8db1SStefano Zampini #undef __FUNCT__ 1089015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 1090015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 1091efc2fbd9SStefano Zampini { 1092efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1093de9d7bd0SStefano Zampini PetscScalar *array; 1094efc2fbd9SStefano Zampini PetscErrorCode ierr; 1095efc2fbd9SStefano Zampini 1096efc2fbd9SStefano Zampini PetscFunctionBegin; 1097efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 1098efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 10994f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1100efc2fbd9SStefano Zampini } 1101de9d7bd0SStefano Zampini if (get) { 1102efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 11034f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 11044f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 1105efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 1106de9d7bd0SStefano Zampini } else { 1107de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 1108de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1109de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1110de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 1111efc2fbd9SStefano Zampini } 1112efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1113efc2fbd9SStefano Zampini } 1114efc2fbd9SStefano Zampini 1115efc2fbd9SStefano Zampini #undef __FUNCT__ 1116c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 1117c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 1118c263805aSStefano Zampini { 1119c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1120c263805aSStefano Zampini PetscErrorCode ierr; 1121c263805aSStefano Zampini 1122c263805aSStefano Zampini PetscFunctionBegin; 1123c263805aSStefano Zampini /* TODO: add error checking 1124c263805aSStefano Zampini - avoid nested pop (or push) calls. 1125c263805aSStefano Zampini - cannot push before pop. 11261c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 1127c263805aSStefano Zampini */ 11284f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1129efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1130efc2fbd9SStefano Zampini } 1131c263805aSStefano Zampini if (pop) { 1132a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 11334f1b2e48SStefano Zampini IS is_p0; 11344f1b2e48SStefano Zampini MatReuse reuse; 1135c263805aSStefano Zampini 1136c263805aSStefano Zampini /* extract B_0 */ 11374f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 11384f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 11394f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 11404f1b2e48SStefano Zampini } 11414f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 11424f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 1143c263805aSStefano Zampini /* remove rows and cols from local problem */ 1144c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 114597d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 11464f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 11474f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 1148a3df083aSStefano Zampini } else { 1149a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1150a3df083aSStefano Zampini PetscScalar *vals; 1151a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 1152a3df083aSStefano Zampini 1153a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 1154a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 1155a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 11560b5adadeSStefano Zampini PetscInt *nnz; 1157a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 1158a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 1159a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1160331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 1161331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1162331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 1163331e053bSStefano Zampini nnz[i] = n - nnz[i]; 1164331e053bSStefano Zampini } 1165331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 1166331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1167331e053bSStefano Zampini } 1168a3df083aSStefano Zampini 1169a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1170a3df083aSStefano Zampini PetscScalar *array; 1171a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 1172a3df083aSStefano Zampini 1173a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 1174a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1175a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1176a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 1177a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1178a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 1179a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 1180a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 1181a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 1182a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 1183a3df083aSStefano Zampini cum = 0; 1184a3df083aSStefano Zampini for (j=0;j<n;j++) { 118522db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 1186a3df083aSStefano Zampini vals[cum] = array[j]; 1187a3df083aSStefano Zampini idxs_ins[cum] = j; 1188a3df083aSStefano Zampini cum++; 1189a3df083aSStefano Zampini } 1190a3df083aSStefano Zampini } 1191a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 1192a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 1193a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1194a3df083aSStefano Zampini } 1195a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1196a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1197a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 1198a3df083aSStefano Zampini } 1199c263805aSStefano Zampini } else { /* push */ 1200a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 12014f1b2e48SStefano Zampini PetscInt i; 12024f1b2e48SStefano Zampini 12034f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 12044f1b2e48SStefano Zampini PetscScalar *B0_vals; 12054f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 12064f1b2e48SStefano Zampini 12074f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 12084f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 12097b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 12104f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 12114f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 12124f1b2e48SStefano Zampini } 1213c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1214c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1215a3df083aSStefano Zampini } else { 1216a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 1217a3df083aSStefano Zampini } 1218c263805aSStefano Zampini } 1219c263805aSStefano Zampini PetscFunctionReturn(0); 1220c263805aSStefano Zampini } 1221c263805aSStefano Zampini 1222c263805aSStefano Zampini #undef __FUNCT__ 1223b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 122408122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 1225b1b3d7a2SStefano Zampini { 1226b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 122708122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 122808122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 122908122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 123008122e43SStefano Zampini PetscScalar *work,lwork; 123108122e43SStefano Zampini PetscScalar *St,*S,*eigv; 123208122e43SStefano Zampini PetscScalar *Sarray,*Starray; 123308122e43SStefano Zampini PetscReal *eigs,thresh; 12341b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 1235f6f667cfSStefano Zampini PetscBool allocated_S_St; 123608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 123708122e43SStefano Zampini PetscReal *rwork; 123808122e43SStefano Zampini #endif 1239b1b3d7a2SStefano Zampini PetscErrorCode ierr; 1240b1b3d7a2SStefano Zampini 1241b1b3d7a2SStefano Zampini PetscFunctionBegin; 1242b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 1243af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 1244af25d912SStefano 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); 124506a4e24aSStefano Zampini 1246fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1247fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1248fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1249fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 12501575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1251fd14bc51SStefano Zampini } 1252fd14bc51SStefano Zampini 1253e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 1254e496cd5dSStefano 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); 1255e496cd5dSStefano Zampini } 1256e496cd5dSStefano Zampini 125708122e43SStefano Zampini /* max size of subsets */ 125808122e43SStefano Zampini mss = 0; 125908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 126008122e43SStefano Zampini PetscInt subset_size; 1261862806e4SStefano Zampini 126208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 126308122e43SStefano Zampini mss = PetscMax(mss,subset_size); 126408122e43SStefano Zampini } 126508122e43SStefano Zampini 126608122e43SStefano Zampini /* min/max and threshold */ 126708122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 1268f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 126908122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 1270f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 1271f6f667cfSStefano Zampini if (nmin) { 1272f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 1273f6f667cfSStefano Zampini } 127408122e43SStefano Zampini 127508122e43SStefano Zampini /* allocate lapack workspace */ 127608122e43SStefano Zampini cum = cum2 = 0; 127708122e43SStefano Zampini maxneigs = 0; 127808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 127908122e43SStefano Zampini PetscInt n,subset_size; 1280f6f667cfSStefano Zampini 128108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 128208122e43SStefano Zampini n = PetscMin(subset_size,nmax); 12839162d606SStefano Zampini cum += subset_size; 12849162d606SStefano Zampini cum2 += subset_size*n; 128508122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 128608122e43SStefano Zampini } 128708122e43SStefano Zampini if (mss) { 12889ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 128908122e43SStefano Zampini PetscBLASInt B_itype = 1; 129008122e43SStefano Zampini PetscBLASInt B_N = mss; 12914c6709b3SStefano Zampini PetscReal zero = 0.0; 12924c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 129308122e43SStefano Zampini 129408122e43SStefano Zampini B_lwork = -1; 129508122e43SStefano Zampini S = NULL; 129608122e43SStefano Zampini St = NULL; 1297a58a30b4SStefano Zampini eigs = NULL; 1298a58a30b4SStefano Zampini eigv = NULL; 1299a58a30b4SStefano Zampini B_iwork = NULL; 1300a58a30b4SStefano Zampini B_ifail = NULL; 1301d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1302d1710679SStefano Zampini rwork = NULL; 1303d1710679SStefano Zampini #endif 13048bec7fa6SStefano Zampini thresh = 1.0; 130508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 130608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 130708122e43SStefano 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)); 130808122e43SStefano Zampini #else 130908122e43SStefano 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)); 131008122e43SStefano Zampini #endif 131108122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 131208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 131308122e43SStefano Zampini } else { 131408122e43SStefano Zampini /* TODO */ 131508122e43SStefano Zampini } 131608122e43SStefano Zampini } else { 131708122e43SStefano Zampini lwork = 0; 131808122e43SStefano Zampini } 131908122e43SStefano Zampini 132008122e43SStefano Zampini nv = 0; 1321d62866d3SStefano 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) */ 1322d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 132308122e43SStefano Zampini } 13244c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 1325f6f667cfSStefano Zampini if (allocated_S_St) { 1326f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 1327f6f667cfSStefano Zampini } 1328f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 132908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 133008122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 133108122e43SStefano Zampini #endif 13329162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 13339162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 13349162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 133508122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 13369162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 133708122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 133808122e43SStefano Zampini 133908122e43SStefano Zampini maxneigs = 0; 134072b8c272SStefano Zampini cum = cumarray = 0; 13419162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 13429162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 1343d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 134408122e43SStefano Zampini const PetscInt *idxs; 134508122e43SStefano Zampini 1346d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 134708122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 134808122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 134908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 135008122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 13519162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 13529162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 135308122e43SStefano Zampini } 1354d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 135508122e43SStefano Zampini } 135608122e43SStefano Zampini 135708122e43SStefano Zampini if (mss) { /* multilevel */ 135808122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 135908122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 136008122e43SStefano Zampini } 136108122e43SStefano Zampini 1362ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 136308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 136408122e43SStefano Zampini const PetscInt *idxs; 13659d54b7f4SStefano Zampini PetscReal upper,lower; 1366862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 136708122e43SStefano Zampini PetscBLASInt B_N; 1368aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 136908122e43SStefano Zampini 13709d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 13719d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 13729d54b7f4SStefano Zampini lower = thresh; 13739d54b7f4SStefano Zampini } else { 13749d54b7f4SStefano Zampini upper = 1./thresh; 13759d54b7f4SStefano Zampini lower = 0.; 13769d54b7f4SStefano Zampini } 1377862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 1378ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 1379f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 1380f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 13819ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 1382aff50787SStefano Zampini PetscInt j,k; 1383aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 1384aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 1385aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 138608122e43SStefano Zampini } 138708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 1388aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 1389aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 1390aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 1391aff50787SStefano Zampini } 139208122e43SStefano Zampini } 139308122e43SStefano Zampini } else { 139408122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 139508122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 139608122e43SStefano Zampini } 13978bec7fa6SStefano Zampini } else { 1398f6f667cfSStefano Zampini S = Sarray + cumarray; 1399f6f667cfSStefano Zampini St = Starray + cumarray; 14008bec7fa6SStefano Zampini } 1401aff50787SStefano Zampini /* see if we can save some work */ 1402b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 1403aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1404aff50787SStefano Zampini } 1405aff50787SStefano Zampini 1406b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 1407aff50787SStefano Zampini B_neigs = 0; 1408aff50787SStefano Zampini } else { 14099ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 141008122e43SStefano Zampini PetscBLASInt B_itype = 1; 1411f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 14124c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 14139552c7c7SStefano Zampini PetscInt nmin_s; 1414b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 141508122e43SStefano Zampini 1416fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 14178bec7fa6SStefano 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]]); 1418fd14bc51SStefano Zampini } 1419d16cbb6bSStefano Zampini 1420b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 1421b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 1422b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 1423b7ab4a40SStefano Zampini } 1424b7ab4a40SStefano Zampini 142508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1426b7ab4a40SStefano Zampini if (compute_range) { 1427d16cbb6bSStefano Zampini 1428d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 142908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 14309d54b7f4SStefano 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)); 143108122e43SStefano Zampini #else 14329d54b7f4SStefano 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)); 143308122e43SStefano Zampini #endif 1434b7ab4a40SStefano Zampini } else if (!same_data) { 1435d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1436d16cbb6bSStefano Zampini B_IL = 1; 1437d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 14389d54b7f4SStefano 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)); 1439d16cbb6bSStefano Zampini #else 14409d54b7f4SStefano 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)); 1441d16cbb6bSStefano Zampini #endif 1442b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 1443b7ab4a40SStefano Zampini PetscInt k; 1444b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 1445b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 1446b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 1447b7ab4a40SStefano Zampini nmin = nmax; 1448b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 1449b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 1450b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 1451b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 1452b7ab4a40SStefano Zampini } 1453d16cbb6bSStefano Zampini } 145408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 145508122e43SStefano Zampini if (B_ierr) { 14566c4ed002SBarry 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); 14576c4ed002SBarry 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); 14586c4ed002SBarry 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); 145908122e43SStefano Zampini } 146008122e43SStefano Zampini 146108122e43SStefano Zampini if (B_neigs > nmax) { 1462fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1463fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1464fd14bc51SStefano Zampini } 14659d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 146608122e43SStefano Zampini B_neigs = nmax; 146708122e43SStefano Zampini } 146808122e43SStefano Zampini 14699552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 14709552c7c7SStefano Zampini if (B_neigs < nmin_s) { 147108122e43SStefano Zampini PetscBLASInt B_neigs2; 147208122e43SStefano Zampini 14739d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1474f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 14759d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 14769d54b7f4SStefano Zampini } else { 14779d54b7f4SStefano Zampini B_IL = B_neigs + 1; 14789d54b7f4SStefano Zampini B_IU = nmin_s; 14799d54b7f4SStefano Zampini } 1480fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1481fd14bc51SStefano 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); 1482fd14bc51SStefano Zampini } 14839ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 14841ae86dd6SStefano Zampini PetscInt j,k; 148508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 14861ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 14871ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 14881ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 148908122e43SStefano Zampini } 149008122e43SStefano Zampini } 149108122e43SStefano Zampini } else { 149208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 149308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 149408122e43SStefano Zampini } 149508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 149608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 14979d54b7f4SStefano 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)); 149808122e43SStefano Zampini #else 14999d54b7f4SStefano 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)); 150008122e43SStefano Zampini #endif 150108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 150208122e43SStefano Zampini B_neigs += B_neigs2; 150308122e43SStefano Zampini } 150408122e43SStefano Zampini if (B_ierr) { 15056c4ed002SBarry 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); 15066c4ed002SBarry 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); 15076c4ed002SBarry 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); 150808122e43SStefano Zampini } 1509fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1510ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 151108122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 151208122e43SStefano Zampini if (eigs[j] == 0.0) { 1513ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 151408122e43SStefano Zampini } else { 15159d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1516ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 15179d54b7f4SStefano Zampini } else { 15189d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 15199d54b7f4SStefano Zampini } 1520fd14bc51SStefano Zampini } 152108122e43SStefano Zampini } 152208122e43SStefano Zampini } 152308122e43SStefano Zampini } else { 152408122e43SStefano Zampini /* TODO */ 152508122e43SStefano Zampini } 1526aff50787SStefano Zampini } 15276c3e6151SStefano Zampini /* change the basis back to the original one */ 15286c3e6151SStefano Zampini if (sub_schurs->change) { 152972b8c272SStefano Zampini Mat change,phi,phit; 15306c3e6151SStefano Zampini 15316c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 15326c3e6151SStefano Zampini PetscInt ii; 15336c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 15346c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 15356c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 15366c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 15376c3e6151SStefano Zampini } 15386c3e6151SStefano Zampini } 15396c3e6151SStefano Zampini } 154072b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 15416c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 154272b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 15436c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 15446c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 15456c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 15466c3e6151SStefano Zampini } 15478bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 15488bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 15499162d606SStefano Zampini if (B_neigs) { 15509162d606SStefano 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); 1551fd14bc51SStefano Zampini 1552fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 15539552c7c7SStefano Zampini PetscInt ii; 15549552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1555ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 15569552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1557ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1558ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1559ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1560ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1561ac47001eSStefano Zampini #else 1562ac47001eSStefano 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); 1563ac47001eSStefano Zampini #endif 15649552c7c7SStefano Zampini } 15659552c7c7SStefano Zampini } 1566fd14bc51SStefano Zampini } 15679162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 15689162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 15699162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 15709162d606SStefano Zampini cum++; 157108122e43SStefano Zampini } 157208122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 157308122e43SStefano Zampini /* shift for next computation */ 157408122e43SStefano Zampini cumarray += subset_size*subset_size; 157508122e43SStefano Zampini } 1576fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1577fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1578fd14bc51SStefano Zampini } 157908122e43SStefano Zampini 158008122e43SStefano Zampini if (mss) { 158108122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 158208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1583f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1584f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1585f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 158608122e43SStefano Zampini } 1587f6f667cfSStefano Zampini if (allocated_S_St) { 1588f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1589f6f667cfSStefano Zampini } 1590f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 159108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 159208122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 159308122e43SStefano Zampini #endif 159408122e43SStefano Zampini if (pcbddc->dbg_flag) { 15951b968477SStefano Zampini PetscInt maxneigs_r; 1596b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 15979b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 159808122e43SStefano Zampini } 159908122e43SStefano Zampini PetscFunctionReturn(0); 160008122e43SStefano Zampini } 1601b1b3d7a2SStefano Zampini 1602674ae819SStefano Zampini #undef __FUNCT__ 1603c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1604c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1605c8587f34SStefano Zampini { 16068629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1607c8587f34SStefano Zampini PetscErrorCode ierr; 1608c8587f34SStefano Zampini 1609c8587f34SStefano Zampini PetscFunctionBegin; 1610f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 16115e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1612c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1613c8587f34SStefano Zampini 1614684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 16150fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1616684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1617c8587f34SStefano Zampini 16188629588bSStefano Zampini /* 16198629588bSStefano Zampini Setup local correction and local part of coarse basis. 16208629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 16218629588bSStefano Zampini */ 162247f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 16238629588bSStefano Zampini 16248629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 16258629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 16268629588bSStefano Zampini 16278629588bSStefano Zampini /* free */ 16288629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1629c8587f34SStefano Zampini PetscFunctionReturn(0); 1630c8587f34SStefano Zampini } 1631c8587f34SStefano Zampini 1632c8587f34SStefano Zampini #undef __FUNCT__ 1633674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1634674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1635674ae819SStefano Zampini { 1636674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1637674ae819SStefano Zampini PetscErrorCode ierr; 1638674ae819SStefano Zampini 1639674ae819SStefano Zampini PetscFunctionBegin; 1640674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1641674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 164230368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1643674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1644785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1645674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1646f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1647f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1648785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 164963602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 165063602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1651674ae819SStefano Zampini PetscFunctionReturn(0); 1652674ae819SStefano Zampini } 1653674ae819SStefano Zampini 1654674ae819SStefano Zampini #undef __FUNCT__ 1655674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1656674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1657674ae819SStefano Zampini { 1658674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16594f1b2e48SStefano Zampini PetscInt i; 1660674ae819SStefano Zampini PetscErrorCode ierr; 1661674ae819SStefano Zampini 1662674ae819SStefano Zampini PetscFunctionBegin; 1663b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1664674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 166516909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 16661dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 1667674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1668669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 1669*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 1670674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 16714f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 16724f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 16734f1b2e48SStefano Zampini } 16744f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1675b334f244SStefano Zampini if (pcbddc->sub_schurs) { 1676b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1677b334f244SStefano Zampini } 1678674ae819SStefano Zampini PetscFunctionReturn(0); 1679674ae819SStefano Zampini } 1680674ae819SStefano Zampini 1681674ae819SStefano Zampini #undef __FUNCT__ 1682674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1683674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1684674ae819SStefano Zampini { 1685674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1686674ae819SStefano Zampini PetscErrorCode ierr; 1687674ae819SStefano Zampini 1688674ae819SStefano Zampini PetscFunctionBegin; 1689674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 169058da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1691ca92afb2SStefano Zampini PetscScalar *array; 169206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 169306656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 169458da7f69SStefano Zampini } 1695674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1696674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 169715aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 169815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1699674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1700674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1701674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 170206656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1703674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1704674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 17058ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1706674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1707674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1708674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1709f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1710f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1711f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1712f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1713727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 17140e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1715f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 171670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 171781d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 17180369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 17191dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 17204f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 17218b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1722ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1723ca92afb2SStefano Zampini PetscInt i; 1724ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1725ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1726ca92afb2SStefano Zampini } 1727ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1728ca92afb2SStefano Zampini } 17294f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1730674ae819SStefano Zampini PetscFunctionReturn(0); 1731674ae819SStefano Zampini } 1732674ae819SStefano Zampini 1733674ae819SStefano Zampini #undef __FUNCT__ 1734f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1735f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 17366bfb1811SStefano Zampini { 17376bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 17386bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 17396bfb1811SStefano Zampini VecType impVecType; 17404f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 17416bfb1811SStefano Zampini PetscErrorCode ierr; 17426bfb1811SStefano Zampini 17436bfb1811SStefano Zampini PetscFunctionBegin; 17446c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1745e7b262bdSStefano Zampini /* get sizes */ 17464f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1747b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 17486bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1749e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1750e7b262bdSStefano Zampini /* R nodes */ 1751e7b262bdSStefano Zampini old_size = -1; 1752e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1753e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1754e7b262bdSStefano Zampini } 1755e7b262bdSStefano Zampini if (n_R != old_size) { 1756e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1757e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 17586bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 17596bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 17606bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 17616bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1762e7b262bdSStefano Zampini } 1763e7b262bdSStefano Zampini /* local primal dofs */ 1764e7b262bdSStefano Zampini old_size = -1; 1765e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1766e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1767e7b262bdSStefano Zampini } 1768e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1769e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 177083b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1771e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 17726bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1773e7b262bdSStefano Zampini } 1774e7b262bdSStefano Zampini /* local explicit constraints */ 1775e7b262bdSStefano Zampini old_size = -1; 1776e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1777e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1778e7b262bdSStefano Zampini } 1779e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1780e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 178183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 178283b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 178383b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 178483b7ccabSStefano Zampini } 17856bfb1811SStefano Zampini PetscFunctionReturn(0); 17866bfb1811SStefano Zampini } 17876bfb1811SStefano Zampini 17886bfb1811SStefano Zampini #undef __FUNCT__ 178947f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 179047f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 179188ebb749SStefano Zampini { 179225084f0cSStefano Zampini PetscErrorCode ierr; 179325084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 179488ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 179588ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1796d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 179725084f0cSStefano Zampini /* submatrices of local problem */ 179880677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 179906656605SStefano Zampini /* submatrices of local coarse problem */ 180006656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 180125084f0cSStefano Zampini /* working matrices */ 180206656605SStefano Zampini Mat C_CR; 180325084f0cSStefano Zampini /* additional working stuff */ 180406656605SStefano Zampini PC pc_R; 18054f1b2e48SStefano Zampini Mat F; 18065cbda25cSStefano Zampini Vec dummy_vec; 1807a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 180825084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 180906656605SStefano Zampini PetscScalar *work; 181006656605SStefano Zampini PetscInt *idx_V_B; 1811ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 181206656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1813ffd830a3SStefano Zampini 181425084f0cSStefano Zampini /* some shortcuts to scalars */ 181506656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 181688ebb749SStefano Zampini 181788ebb749SStefano Zampini PetscFunctionBegin; 1818ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1819ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1820ffd830a3SStefano Zampini } 1821ffd830a3SStefano Zampini 1822ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1823b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 18244f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1825b371cd4fSStefano Zampini n_B = pcis->n_B; 1826b371cd4fSStefano Zampini n_D = pcis->n - n_B; 182788ebb749SStefano Zampini n_R = pcis->n - n_vertices; 182888ebb749SStefano Zampini 182988ebb749SStefano Zampini /* vertices in boundary numbering */ 1830785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 18310e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 18326c4ed002SBarry 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); 183388ebb749SStefano Zampini 183406656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1835019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 183606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 183706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 183806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 183906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 184006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 184106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 184206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 184306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 184406656605SStefano Zampini 184506656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 184606656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 184706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 184806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 184906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1850ffd830a3SStefano Zampini lda_rhs = n_R; 1851a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 185206656605SStefano Zampini if (isLU || isILU || isCHOL) { 185306656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1854b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 1855df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1856d62866d3SStefano Zampini MatFactorType type; 1857d62866d3SStefano Zampini 1858df4d28bfSStefano Zampini F = reuse_solver->F; 18596816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1860d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1861ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 186222db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 186306656605SStefano Zampini } else { 186406656605SStefano Zampini F = NULL; 186506656605SStefano Zampini } 186606656605SStefano Zampini 1867ffd830a3SStefano Zampini /* allocate workspace */ 1868ffd830a3SStefano Zampini n = 0; 1869ffd830a3SStefano Zampini if (n_constraints) { 1870ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1871ffd830a3SStefano Zampini } 1872ffd830a3SStefano Zampini if (n_vertices) { 1873ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1874ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1875ffd830a3SStefano Zampini } 1876ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1877ffd830a3SStefano Zampini 18785cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 18795cbda25cSStefano Zampini dummy_vec = NULL; 18805cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 18815cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 18825cbda25cSStefano Zampini } 18835cbda25cSStefano Zampini 188488ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 188588ebb749SStefano Zampini if (n_constraints) { 188672b8c272SStefano Zampini Mat M1,M2,M3,C_B; 188706656605SStefano Zampini IS is_aux; 188880677318SStefano Zampini PetscScalar *array,*array2; 188906656605SStefano Zampini 1890f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 189180677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 189288ebb749SStefano Zampini 189325084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 189425084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 18958ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 189672b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 189788ebb749SStefano Zampini 189880677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 189980677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1900ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 190188ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 190206656605SStefano Zampini const PetscScalar *row_cmat_values; 190306656605SStefano Zampini const PetscInt *row_cmat_indices; 190406656605SStefano Zampini PetscInt size_of_constraint,j; 190588ebb749SStefano Zampini 190606656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 190706656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1908ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 190906656605SStefano Zampini } 191006656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 191106656605SStefano Zampini } 1912ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 191306656605SStefano Zampini if (F) { 191406656605SStefano Zampini Mat B; 191506656605SStefano Zampini 1916ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1917a3df083aSStefano Zampini if (need_benign_correction) { 1918df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1919a3df083aSStefano Zampini 192072b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 192172b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 1922a3df083aSStefano Zampini } 192380677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1924a3df083aSStefano Zampini if (need_benign_correction) { 1925a3df083aSStefano Zampini PetscScalar *marr; 1926df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1927a3df083aSStefano Zampini 1928a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 19295cbda25cSStefano Zampini if (lda_rhs != n_R) { 19305cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 19315cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 19325cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 19335cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 19345cbda25cSStefano Zampini } 19355cbda25cSStefano Zampini } else { 1936a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1937a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 19385cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 1939a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1940a3df083aSStefano Zampini } 19415cbda25cSStefano Zampini } 1942a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1943a3df083aSStefano Zampini } 194406656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 194506656605SStefano Zampini } else { 194680677318SStefano Zampini PetscScalar *marr; 194780677318SStefano Zampini 194880677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 194906656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1950ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1951ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 195206656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 195306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 195406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 195506656605SStefano Zampini } 195680677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 195706656605SStefano Zampini } 195880677318SStefano Zampini if (!pcbddc->switch_static) { 195980677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 196080677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 196180677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 196280677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1963ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 196480677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 196580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196780677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 196880677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 196980677318SStefano Zampini } 197080677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 197180677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 197272b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 197380677318SStefano Zampini } else { 1974ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1975ffd830a3SStefano Zampini IS dummy; 1976ffd830a3SStefano Zampini 1977ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 197872b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1979ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1980ffd830a3SStefano Zampini } else { 198180677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 198280677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1983ffd830a3SStefano Zampini } 198425084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 198580677318SStefano Zampini } 198680677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 198780677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 198880677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 198906656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 199006656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 199180677318SStefano Zampini if (isCHOL) { 199280677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 199380677318SStefano Zampini } else { 199425084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 199580677318SStefano Zampini } 199680677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 199706656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 199825084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 199925084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 200025084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 200180677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 200272b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 200372b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 200406656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 200506656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 2006f4ddd8eeSStefano Zampini } 2007fc227af8SStefano Zampini 2008fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 200988ebb749SStefano Zampini if (n_vertices) { 201006656605SStefano Zampini IS is_aux; 20113a50541eSStefano Zampini 2012b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 20136816873aSStefano Zampini IS tis; 20146816873aSStefano Zampini 20156816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 20166816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 20176816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 20186816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 20196816873aSStefano Zampini } else { 20203a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 20216816873aSStefano Zampini } 20229577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 20239577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 202404708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 202525084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 202688ebb749SStefano Zampini } 202788ebb749SStefano Zampini 202888ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 2029f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 203006656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 203106656605SStefano Zampini if (pcbddc->coarse_phi_D) { 203206656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 203306656605SStefano Zampini } 2034f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 203506656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 203606656605SStefano Zampini PetscScalar *marray; 203706656605SStefano Zampini 203806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 203906656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 2040f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2041f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 2042f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 2043f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2044f4ddd8eeSStefano Zampini } 2045f4ddd8eeSStefano Zampini } 204606656605SStefano Zampini 2047f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 204806656605SStefano Zampini PetscScalar *marray; 204988ebb749SStefano Zampini 205006656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 20518eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 205206656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 205388ebb749SStefano Zampini } 20543301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 205506656605SStefano Zampini n *= 2; 205688ebb749SStefano Zampini } 205706656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 205806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 205906656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 20608eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 206106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 206206656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 206388ebb749SStefano Zampini } 20643301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 206506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 20668eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 206706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 206806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 206988ebb749SStefano Zampini } 207088ebb749SStefano Zampini } else { 2071c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 2072c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 20731b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2074c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 2075c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 2076c0553b1fSStefano Zampini } 207788ebb749SStefano Zampini } 207806656605SStefano Zampini } 2079019a44ceSStefano Zampini 208006656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 20814f1b2e48SStefano Zampini p0_lidx_I = NULL; 20824f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 2083d12edf2fSStefano Zampini const PetscInt *idxs; 2084d12edf2fSStefano Zampini 2085d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 20864f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 20874f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20884f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 20894f1b2e48SStefano Zampini } 2090d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 2091d12edf2fSStefano Zampini } 2092d16cbb6bSStefano Zampini 209306656605SStefano Zampini /* vertices */ 209406656605SStefano Zampini if (n_vertices) { 209516f15bc4SStefano Zampini 2096af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 209704708bb6SStefano Zampini 209816f15bc4SStefano Zampini if (n_R) { 209914393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 210006656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 210116f15bc4SStefano Zampini PetscScalar *x,*y; 210204708bb6SStefano Zampini PetscBool isseqaij; 210306656605SStefano Zampini 210421eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 210514393ed6SStefano Zampini if (need_benign_correction) { 210614393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 210714393ed6SStefano Zampini IS is_p0; 210814393ed6SStefano Zampini PetscInt *idxs_p0,n; 210914393ed6SStefano Zampini 211014393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 211114393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 211214393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 2113af25d912SStefano 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); 211414393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 211514393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 211614393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 211714393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 211814393ed6SStefano Zampini } 211914393ed6SStefano Zampini 2120ffd830a3SStefano Zampini if (lda_rhs == n_R) { 2121af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2122ffd830a3SStefano Zampini } else { 2123ca92afb2SStefano Zampini PetscScalar *av,*array; 2124ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 2125ca92afb2SStefano Zampini PetscInt n; 2126ca92afb2SStefano Zampini PetscBool flg_row; 2127ffd830a3SStefano Zampini 2128ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 2129ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 21309d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2131ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2132ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 2133ca92afb2SStefano Zampini for (i=0;i<n;i++) { 2134ca92afb2SStefano Zampini PetscInt j; 2135ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 2136ffd830a3SStefano Zampini } 2137ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2138ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2139ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 2140ffd830a3SStefano Zampini } 2141ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2142a3df083aSStefano Zampini if (need_benign_correction) { 2143df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2144a3df083aSStefano Zampini PetscScalar *marr; 2145a3df083aSStefano Zampini 2146a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 214714393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 214814393ed6SStefano Zampini 214914393ed6SStefano Zampini | 0 0 0 | (V) 215014393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 215114393ed6SStefano Zampini | 0 0 -1 | (p0) 215214393ed6SStefano Zampini 215314393ed6SStefano Zampini */ 2154df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 215514393ed6SStefano Zampini const PetscScalar *vals; 215614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 215714393ed6SStefano Zampini PetscInt n,j,nz; 215814393ed6SStefano Zampini 2159df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2160df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 216114393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 216214393ed6SStefano Zampini for (j=0;j<n;j++) { 216314393ed6SStefano Zampini PetscScalar val = vals[j]; 216414393ed6SStefano Zampini PetscInt k,col = idxs[j]; 216514393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 216614393ed6SStefano Zampini } 216714393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2168df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 216914393ed6SStefano Zampini } 217072b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 217172b8c272SStefano Zampini } 217272b8c272SStefano Zampini if (F) { 217314393ed6SStefano Zampini /* need to correct the rhs */ 217472b8c272SStefano Zampini if (need_benign_correction) { 217572b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 217672b8c272SStefano Zampini PetscScalar *marr; 217772b8c272SStefano Zampini 217872b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 21795cbda25cSStefano Zampini if (lda_rhs != n_R) { 21805cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 21815cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 21825cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 21835cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 21845cbda25cSStefano Zampini } 21855cbda25cSStefano Zampini } else { 2186a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2187a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 21885cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2189a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2190a3df083aSStefano Zampini } 21915cbda25cSStefano Zampini } 2192a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 2193a3df083aSStefano Zampini } 219406656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 219514393ed6SStefano Zampini /* need to correct the solution */ 2196a3df083aSStefano Zampini if (need_benign_correction) { 2197df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2198a3df083aSStefano Zampini PetscScalar *marr; 2199a3df083aSStefano Zampini 2200a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 22015cbda25cSStefano Zampini if (lda_rhs != n_R) { 22025cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 22035cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 22045cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 22055cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 22065cbda25cSStefano Zampini } 22075cbda25cSStefano Zampini } else { 2208a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2209a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 22105cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2211a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2212a3df083aSStefano Zampini } 22135cbda25cSStefano Zampini } 2214a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 2215a3df083aSStefano Zampini } 221606656605SStefano Zampini } else { 221706656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 221806656605SStefano Zampini for (i=0;i<n_vertices;i++) { 2219ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 2220ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 222106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 222206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 222306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 222406656605SStefano Zampini } 222506656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 222606656605SStefano Zampini } 222780677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2228ffd830a3SStefano Zampini /* S_VV and S_CV */ 222906656605SStefano Zampini if (n_constraints) { 223006656605SStefano Zampini Mat B; 223180677318SStefano Zampini 2232ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 223380677318SStefano Zampini for (i=0;i<n_vertices;i++) { 2234ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 2235ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 223680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 223780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 223880677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 223980677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 224080677318SStefano Zampini } 2241ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 224280677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 224380677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 2244ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 224580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 224606656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 2247ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 2248ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 224906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 225006656605SStefano Zampini } 225104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 225204708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 2253511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 225404708bb6SStefano Zampini } 2255ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2256ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 2257ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2258ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 2259ffd830a3SStefano Zampini } 226006656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 226114393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 226214393ed6SStefano Zampini if (need_benign_correction) { 2263df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 226414393ed6SStefano Zampini PetscScalar *marr,*sums; 226514393ed6SStefano Zampini 226614393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 226714393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 2268df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 226914393ed6SStefano Zampini const PetscScalar *vals; 227014393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 227114393ed6SStefano Zampini PetscInt n,j,nz; 227214393ed6SStefano Zampini 2273df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2274df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 227514393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 227614393ed6SStefano Zampini PetscInt k; 227714393ed6SStefano Zampini sums[j] = 0.; 227814393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 227914393ed6SStefano Zampini } 228014393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 228114393ed6SStefano Zampini for (j=0;j<n;j++) { 228214393ed6SStefano Zampini PetscScalar val = vals[j]; 228314393ed6SStefano Zampini PetscInt k; 228414393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 228514393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 228614393ed6SStefano Zampini } 228714393ed6SStefano Zampini } 228814393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2289df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 229014393ed6SStefano Zampini } 229114393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 229214393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 229314393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 229414393ed6SStefano Zampini } 229580677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 229606656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 229706656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 229806656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 229906656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 230006656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 230106656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 230206656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2303d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 2304019a44ceSStefano Zampini } else { 2305d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2306d16cbb6bSStefano Zampini } 230721eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 2308d16cbb6bSStefano Zampini 230906656605SStefano Zampini /* coarse basis functions */ 231006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 231116f15bc4SStefano Zampini PetscScalar *y; 231216f15bc4SStefano Zampini 2313ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 231406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 231506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 231606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 231706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 231806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 231906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 232006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 232106656605SStefano Zampini 232206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 23234f1b2e48SStefano Zampini PetscInt j; 23244f1b2e48SStefano Zampini 232506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 232606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 232706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 23304f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 233106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 233206656605SStefano Zampini } 233306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 233406656605SStefano Zampini } 233504708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 233604708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 233706656605SStefano Zampini } 23385cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 233906656605SStefano Zampini 234006656605SStefano Zampini if (n_constraints) { 234106656605SStefano Zampini Mat B; 234206656605SStefano Zampini 2343ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 234406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 234580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 234606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 234706656605SStefano Zampini if (n_vertices) { 234880677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 234980677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 235080677318SStefano Zampini } else { 235180677318SStefano Zampini Mat S_VCt; 235280677318SStefano Zampini 2353ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2354ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 235572b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 2356ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 2357ffd830a3SStefano Zampini } 235880677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 235980677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 236080677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 236180677318SStefano Zampini } 236206656605SStefano Zampini } 236306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 236406656605SStefano Zampini /* coarse basis functions */ 236506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 236606656605SStefano Zampini PetscScalar *y; 236706656605SStefano Zampini 2368ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 236906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 237006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 237106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 237206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 237306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 237406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 237506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 23764f1b2e48SStefano Zampini PetscInt j; 23774f1b2e48SStefano Zampini 237806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 237906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 238006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 238106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 238206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 23834f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 238406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 238506656605SStefano Zampini } 238606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 238706656605SStefano Zampini } 238806656605SStefano Zampini } 238980677318SStefano Zampini if (n_constraints) { 239080677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 239180677318SStefano Zampini } 23924f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 239372b8c272SStefano Zampini 239472b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 239572b8c272SStefano Zampini if (pcbddc->benign_n) { 239672b8c272SStefano Zampini Mat B0_B,B0_BPHI; 239772b8c272SStefano Zampini IS is_dummy; 239872b8c272SStefano Zampini PetscScalar *data; 239972b8c272SStefano Zampini PetscInt j; 240072b8c272SStefano Zampini 240172b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 240272b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 240372b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 240472b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 240586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 240672b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 240772b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 240872b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 240972b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 241072b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 241172b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 241272b8c272SStefano Zampini } 241372b8c272SStefano Zampini } 241472b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 241572b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 241672b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 241772b8c272SStefano Zampini } 2418019a44ceSStefano Zampini 241906656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 24203301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 2421ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 2422ffd830a3SStefano Zampini PetscScalar *marray; 242306656605SStefano Zampini 242406656605SStefano Zampini if (n_constraints) { 2425ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 242606656605SStefano Zampini 2427af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 242806656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 2429ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 243016f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 243106656605SStefano Zampini if (n_vertices) { 2432ffd830a3SStefano Zampini Mat S_VCT; 243306656605SStefano Zampini 243406656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 2435ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 243616f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 243706656605SStefano Zampini } 2438ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 24395b782168SStefano Zampini } else { 24405b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 244106656605SStefano Zampini } 244216f15bc4SStefano Zampini if (n_vertices && n_R) { 2443ffd830a3SStefano Zampini PetscScalar *av,*marray; 2444ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 2445ffd830a3SStefano Zampini PetscInt n; 2446ffd830a3SStefano Zampini PetscBool flg_row; 244706656605SStefano Zampini 2448ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 2449af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 2450ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2451ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 2452ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2453ffd830a3SStefano Zampini for (i=0;i<n;i++) { 2454ffd830a3SStefano Zampini PetscInt j; 2455ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 2456ffd830a3SStefano Zampini } 2457ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2458ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2459ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 246006656605SStefano Zampini } 246106656605SStefano Zampini 2462ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 2463ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2464ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 2465ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 2466ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 246706656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 246806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 246906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 247006656605SStefano Zampini } 2471ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 24725b782168SStefano Zampini if (B_C) { 2473ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 2474ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 2475ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 2476ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 2477ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2478ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2479ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 248006656605SStefano Zampini } 2481ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 24825b782168SStefano Zampini } 24835b782168SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 24845b782168SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 24855b782168SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 24865b782168SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 24875b782168SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 24885b782168SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 24895b782168SStefano Zampini } 24905b782168SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 249106656605SStefano Zampini /* coarse basis functions */ 249206656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 249306656605SStefano Zampini PetscScalar *y; 249406656605SStefano Zampini 2495ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 249606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 249706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 249806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 250006656605SStefano Zampini if (i<n_vertices) { 250106656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 250206656605SStefano Zampini } 250306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 250406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 250506656605SStefano Zampini 250606656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 250706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 250806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 250906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 251006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 251106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 251206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 251306656605SStefano Zampini } 251406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 251506656605SStefano Zampini } 2516ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2517ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 251806656605SStefano Zampini } 2519d62866d3SStefano Zampini /* free memory */ 252088ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 252106656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 252206656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 252306656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 252406656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2525d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2526d62866d3SStefano Zampini if (n_vertices) { 2527d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2528d62866d3SStefano Zampini } 2529d62866d3SStefano Zampini if (n_constraints) { 2530d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2531d62866d3SStefano Zampini } 253288ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 253388ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 253488ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2535d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 253688ebb749SStefano Zampini Mat coarse_sub_mat; 253725084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 253888ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 253988ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 254088ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 25418bec7fa6SStefano Zampini Mat C_B,CPHI; 25428bec7fa6SStefano Zampini IS is_dummy; 25438bec7fa6SStefano Zampini Vec mones; 254488ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 254588ebb749SStefano Zampini PetscReal real_value; 254688ebb749SStefano Zampini 2547a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2548a3df083aSStefano Zampini Mat A; 2549a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2550a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2551a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2552a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2553a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2554a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2555a3df083aSStefano Zampini } else { 255688ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 255788ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 255888ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 255988ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2560a3df083aSStefano Zampini } 256188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 256288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2563ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 256488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 256588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 256688ebb749SStefano Zampini } 256788ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 256888ebb749SStefano Zampini 256925084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 25703301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 257125084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2572ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 257388ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 257488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 257588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 257688ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 257788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 257888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 257988ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 258088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 258188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 258288ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 258388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 258488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 258588ebb749SStefano Zampini } else { 258688ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 258788ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 258888ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 258988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 259088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 259188ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 259288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 259388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 259488ebb749SStefano Zampini } 259588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 259688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 259788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2598511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 25994f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2600fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 2601d12edf2fSStefano Zampini PetscScalar *data,*data2; 26024f1b2e48SStefano Zampini PetscInt j; 2603d12edf2fSStefano Zampini 26044f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2605fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 2606d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 260786c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2608d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2609d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 26104f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 26114f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2612d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 26134f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 26144f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 26154f1b2e48SStefano Zampini } 2616d12edf2fSStefano Zampini } 2617d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2618d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2619d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2620d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2621d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2622d12edf2fSStefano Zampini } 2623d12edf2fSStefano Zampini #if 0 2624d12edf2fSStefano Zampini { 2625d12edf2fSStefano Zampini PetscViewer viewer; 2626d12edf2fSStefano Zampini char filename[256]; 2627ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2628d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2629d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2630ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2631ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2632ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2633d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 263472b8c272SStefano Zampini if (save_change) { 263572b8c272SStefano Zampini Mat phi_B; 263672b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 263772b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 263872b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 263972b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 264072b8c272SStefano Zampini } else { 2641ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2642ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 264372b8c272SStefano Zampini } 2644ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2645ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2646ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2647ffd830a3SStefano Zampini } 2648ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2649ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2650ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2651ffd830a3SStefano Zampini } 265272b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 2653ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2654ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2655ffd830a3SStefano Zampini } 2656d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2657d12edf2fSStefano Zampini } 2658d12edf2fSStefano Zampini #endif 265981d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 26608bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 26611575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 266206656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 26638bec7fa6SStefano Zampini 26648bec7fa6SStefano Zampini /* check constraints */ 2665a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2666a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 26674f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 26688bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2669a00504b5SStefano Zampini } else { 2670a00504b5SStefano Zampini PetscScalar *data; 2671a00504b5SStefano Zampini Mat tmat; 2672a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2673a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 2674a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2675a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2676a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2677a00504b5SStefano Zampini } 26788bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 26798bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 26808bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 26818bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2682bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2683ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2684bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2685bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2686bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2687bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2688bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 268988ebb749SStefano Zampini } 26908bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 26918bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 26928bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 26938bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 269425084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 269588ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 269688ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 269788ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 269888ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 269988ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 270088ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 270188ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 270288ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 270388ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 270488ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2705ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 270688ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 270788ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 270888ebb749SStefano Zampini } 270988ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 271088ebb749SStefano Zampini } 27118629588bSStefano Zampini /* get back data */ 27128629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 271388ebb749SStefano Zampini PetscFunctionReturn(0); 271488ebb749SStefano Zampini } 271588ebb749SStefano Zampini 271688ebb749SStefano Zampini #undef __FUNCT__ 2717d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2718d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2719aa0d41d4SStefano Zampini { 2720d65f70fdSStefano Zampini Mat *work_mat; 2721d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2722d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2723c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 2724aa0d41d4SStefano Zampini PetscErrorCode ierr; 2725aa0d41d4SStefano Zampini 2726aa0d41d4SStefano Zampini PetscFunctionBegin; 2727d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2728d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2729d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2730d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2731aa0d41d4SStefano Zampini 2732d65f70fdSStefano Zampini if (!rsorted) { 2733906d46d4SStefano Zampini const PetscInt *idxs; 2734906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2735aa0d41d4SStefano Zampini 2736d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2737d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2738d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2739d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2740aa0d41d4SStefano Zampini } 2741d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2742d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2743d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2744d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2745aa0d41d4SStefano Zampini } 2746d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2747d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2748d65f70fdSStefano Zampini } else { 2749d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2750d65f70fdSStefano Zampini isrow_s = isrow; 2751aa0d41d4SStefano Zampini } 2752906d46d4SStefano Zampini 2753d65f70fdSStefano Zampini if (!csorted) { 2754d65f70fdSStefano Zampini if (isrow == iscol) { 2755d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2756d65f70fdSStefano Zampini iscol_s = isrow_s; 2757d65f70fdSStefano Zampini } else { 2758d65f70fdSStefano Zampini const PetscInt *idxs; 2759d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2760906d46d4SStefano Zampini 2761d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2762d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2763d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2764d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2765d65f70fdSStefano Zampini } 2766d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2767d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2768d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2769d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2770d65f70fdSStefano Zampini } 2771d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2772d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2773d65f70fdSStefano Zampini } 2774d65f70fdSStefano Zampini } else { 2775d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2776d65f70fdSStefano Zampini iscol_s = iscol; 2777d65f70fdSStefano Zampini } 2778d65f70fdSStefano Zampini 2779d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2780d65f70fdSStefano Zampini 2781d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2782906d46d4SStefano Zampini Mat new_mat; 2783d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2784906d46d4SStefano Zampini 2785d65f70fdSStefano Zampini if (!rsorted) { 2786d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2787d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2788d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2789d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2790906d46d4SStefano Zampini } 2791d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2792d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2793d65f70fdSStefano Zampini } else { 2794d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2795906d46d4SStefano Zampini } 2796d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2797d65f70fdSStefano Zampini 2798d65f70fdSStefano Zampini if (!csorted) { 2799d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2800d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2801d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2802d65f70fdSStefano Zampini } else { 2803d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2804d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2805d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2806d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2807d65f70fdSStefano Zampini } 2808d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2809d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2810d65f70fdSStefano Zampini } 2811d65f70fdSStefano Zampini } else { 2812d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2813d65f70fdSStefano Zampini } 2814d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2815d65f70fdSStefano Zampini 2816d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2817d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2818d65f70fdSStefano Zampini work_mat[0] = new_mat; 2819d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2820d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2821d65f70fdSStefano Zampini } 2822d65f70fdSStefano Zampini 2823d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2824d65f70fdSStefano Zampini *B = work_mat[0]; 2825d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2826d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2827d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2828d65f70fdSStefano Zampini PetscFunctionReturn(0); 2829d65f70fdSStefano Zampini } 2830d65f70fdSStefano Zampini 2831d65f70fdSStefano Zampini #undef __FUNCT__ 28325e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 28335e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2834aa0d41d4SStefano Zampini { 2835aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 28365e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2837d65f70fdSStefano Zampini Mat new_mat; 28385e8657edSStefano Zampini IS is_local,is_global; 2839d65f70fdSStefano Zampini PetscInt local_size; 2840d65f70fdSStefano Zampini PetscBool isseqaij; 2841aa0d41d4SStefano Zampini PetscErrorCode ierr; 2842aa0d41d4SStefano Zampini 2843aa0d41d4SStefano Zampini PetscFunctionBegin; 2844aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 28455e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 28465e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2847b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2848aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2849d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2850aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2851906d46d4SStefano Zampini 2852906d46d4SStefano Zampini /* check */ 2853906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2854906d46d4SStefano Zampini Vec x,x_change; 2855906d46d4SStefano Zampini PetscReal error; 2856906d46d4SStefano Zampini 28575e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2858906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 28595e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2860e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2861e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2862d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2863e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2864e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2865906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2866906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2867906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2868906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2869906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2870906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2871906d46d4SStefano Zampini } 2872906d46d4SStefano Zampini 287322d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 28749b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 287522d5777bSStefano Zampini if (isseqaij) { 2876a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2877a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 2878aa0d41d4SStefano Zampini } else { 2879a00504b5SStefano Zampini Mat work_mat; 28801cf9b237SStefano Zampini 2881a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2882aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2883a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 28841d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2885aa0d41d4SStefano Zampini } 28863301b35fSStefano Zampini if (matis->A->symmetric_set) { 28873301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2888e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 28893301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2890e496cd5dSStefano Zampini #endif 28913301b35fSStefano Zampini } 2892d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2893aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2894aa0d41d4SStefano Zampini } 2895aa0d41d4SStefano Zampini 2896aa0d41d4SStefano Zampini #undef __FUNCT__ 2897a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 28988ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2899a64d13efSStefano Zampini { 2900a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2901a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2902d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 290353892102SStefano Zampini PetscInt *idx_R_local=NULL; 29043a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 29053a50541eSStefano Zampini PetscInt vbs,bs; 29066816873aSStefano Zampini PetscBT bitmask=NULL; 2907a64d13efSStefano Zampini PetscErrorCode ierr; 2908a64d13efSStefano Zampini 2909a64d13efSStefano Zampini PetscFunctionBegin; 2910b23d619eSStefano Zampini /* 2911b23d619eSStefano Zampini No need to setup local scatters if 2912b23d619eSStefano Zampini - primal space is unchanged 2913b23d619eSStefano Zampini AND 2914b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2915b23d619eSStefano Zampini AND 2916b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2917b23d619eSStefano Zampini */ 2918b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2919f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2920f4ddd8eeSStefano Zampini } 2921f4ddd8eeSStefano Zampini /* destroy old objects */ 2922f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2923f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2924f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2925a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2926b371cd4fSStefano Zampini n_B = pcis->n_B; 2927b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2928b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 29293a50541eSStefano Zampini 2930a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 29316816873aSStefano Zampini 293253892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 2933b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 2934854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2935a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2936a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 29370e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2938a64d13efSStefano Zampini } 2939a64d13efSStefano Zampini 2940a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 29414641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 29426816873aSStefano Zampini idx_R_local[n_R++] = i; 2943a64d13efSStefano Zampini } 2944a64d13efSStefano Zampini } 2945df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 2946df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 29476816873aSStefano Zampini 2948df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2949df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 29506816873aSStefano Zampini } 29513a50541eSStefano Zampini 29523a50541eSStefano Zampini /* Block code */ 29533a50541eSStefano Zampini vbs = 1; 29543a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 29553a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 29563a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 29573a50541eSStefano Zampini PetscInt *vary; 2958b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 2959785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 29603a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2961d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2962d3df7717SStefano 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 */ 29630e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2964d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 29653a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 29663a50541eSStefano Zampini is_blocked = PETSC_FALSE; 29673a50541eSStefano Zampini break; 29683a50541eSStefano Zampini } 29693a50541eSStefano Zampini } 2970d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2971d3df7717SStefano Zampini } else { 2972d3df7717SStefano Zampini /* Verify directly the R set */ 2973d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2974d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2975d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2976d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2977d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2978d3df7717SStefano Zampini break; 2979d3df7717SStefano Zampini } 2980d3df7717SStefano Zampini } 2981d3df7717SStefano Zampini } 2982d3df7717SStefano Zampini } 29833a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 29843a50541eSStefano Zampini vbs = bs; 29853a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 29863a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 29873a50541eSStefano Zampini } 29883a50541eSStefano Zampini } 29893a50541eSStefano Zampini } 29903a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 2991b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 2992df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 299353892102SStefano Zampini 2994df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2995df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 299653892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 2997df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 299853892102SStefano Zampini } else { 29993a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 300053892102SStefano Zampini } 3001a64d13efSStefano Zampini 3002a64d13efSStefano Zampini /* print some info if requested */ 3003a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 3004a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3005a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 30061575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3007a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 3008a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 30094f1b2e48SStefano 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); 3010a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3011a64d13efSStefano Zampini } 3012a64d13efSStefano Zampini 3013a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 3014b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 30156816873aSStefano Zampini IS is_aux1,is_aux2; 30166816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 30176816873aSStefano Zampini 30183a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3019854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 3020854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 3021a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 30224641a718SStefano Zampini for (i=0; i<n_D; i++) { 30234641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 30244641a718SStefano Zampini } 3025a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3026a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 30274641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 30284641a718SStefano Zampini aux_array1[j++] = i; 3029a64d13efSStefano Zampini } 3030a64d13efSStefano Zampini } 3031a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3032a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3033a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 30344641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 30354641a718SStefano Zampini aux_array2[j++] = i; 3036a64d13efSStefano Zampini } 3037a64d13efSStefano Zampini } 3038a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3039a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 3040a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 3041a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3042a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 3043a64d13efSStefano Zampini 30448eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3045785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 3046a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 30474641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 30484641a718SStefano Zampini aux_array1[j++] = i; 3049a64d13efSStefano Zampini } 3050a64d13efSStefano Zampini } 3051a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3052a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 3053a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3054a64d13efSStefano Zampini } 30554641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 30563a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3057d62866d3SStefano Zampini } else { 3058df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 30596816873aSStefano Zampini IS tis; 30606816873aSStefano Zampini PetscInt schur_size; 30616816873aSStefano Zampini 3062df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 30636816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 3064df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 30656816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 30666816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 30676816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 30686816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 30696816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 3070d62866d3SStefano Zampini } 3071d62866d3SStefano Zampini } 3072a64d13efSStefano Zampini PetscFunctionReturn(0); 3073a64d13efSStefano Zampini } 3074a64d13efSStefano Zampini 3075304d26faSStefano Zampini 3076304d26faSStefano Zampini #undef __FUNCT__ 3077304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 3078684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 3079304d26faSStefano Zampini { 3080304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3081304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3082304d26faSStefano Zampini PC pc_temp; 3083304d26faSStefano Zampini Mat A_RR; 3084f4ddd8eeSStefano Zampini MatReuse reuse; 3085304d26faSStefano Zampini PetscScalar m_one = -1.0; 3086304d26faSStefano Zampini PetscReal value; 308704708bb6SStefano Zampini PetscInt n_D,n_R; 3088c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 3089304d26faSStefano Zampini PetscErrorCode ierr; 3090e604994aSStefano Zampini /* prefixes stuff */ 3091312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 3092e604994aSStefano Zampini size_t len; 3093304d26faSStefano Zampini 3094304d26faSStefano Zampini PetscFunctionBegin; 3095304d26faSStefano Zampini 3096e604994aSStefano Zampini /* compute prefixes */ 3097e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 3098e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 3099e604994aSStefano Zampini if (!pcbddc->current_level) { 3100e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3101e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3102e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3103e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3104e604994aSStefano Zampini } else { 3105e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 3106312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 3107e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 3108e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 3109312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 3110312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 311134d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 311234d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 3113e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3114e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3115e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 3116e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 3117e604994aSStefano Zampini } 3118e604994aSStefano Zampini 3119304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 3120684f6988SStefano Zampini if (dirichlet) { 3121d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3122450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3123b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 3124450f8f5eSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 3125450f8f5eSStefano Zampini } 3126450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 3127a3df083aSStefano Zampini Mat A_IIn; 3128a3df083aSStefano Zampini 3129a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 3130a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 3131a3df083aSStefano Zampini pcis->A_II = A_IIn; 3132a3df083aSStefano Zampini } 3133450f8f5eSStefano Zampini } 31343301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 31353301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 3136964fefecSStefano Zampini } 3137ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 3138964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 3139304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 3140304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 3141304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 3142304d26faSStefano Zampini /* default */ 3143304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 3144e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 31459577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 3146304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 31479577ea80SStefano Zampini if (issbaij) { 31489577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 31499577ea80SStefano Zampini } else { 3150304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 31519577ea80SStefano Zampini } 3152304d26faSStefano Zampini /* Allow user's customization */ 3153304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 3154304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3155304d26faSStefano Zampini } 3156d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 3157b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3158df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3159d62866d3SStefano Zampini 3160df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 3161d5574798SStefano Zampini } 3162304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3163304d26faSStefano Zampini if (!n_D) { 3164304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 3165304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3166304d26faSStefano Zampini } 3167304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 3168304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 3169304d26faSStefano Zampini /* set ksp_D into pcis data */ 3170304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 3171304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 3172304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 3173684f6988SStefano Zampini } 3174304d26faSStefano Zampini 3175304d26faSStefano Zampini /* NEUMANN PROBLEM */ 3176684f6988SStefano Zampini A_RR = 0; 3177684f6988SStefano Zampini if (neumann) { 3178d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 317904708bb6SStefano Zampini PetscInt ibs,mbs; 318004708bb6SStefano Zampini PetscBool issbaij; 318104708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3182f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 31838ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 3184f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 3185f4ddd8eeSStefano Zampini PetscInt nn_R; 318681d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 3187f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3188f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 3189f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 3190f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 3191f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3192f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3193f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 3194727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 3195f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3196f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3197f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 3198f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 3199f4ddd8eeSStefano Zampini } 3200f4ddd8eeSStefano Zampini } 3201f4ddd8eeSStefano Zampini /* last check */ 3202d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 3203f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3204f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3205f4ddd8eeSStefano Zampini } 3206f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 3207f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3208f4ddd8eeSStefano Zampini } 3209a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 3210af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 3211af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 321204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 321304708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 321404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 321504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 321604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 3217af732b37SStefano Zampini } else { 3218511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 32196816873aSStefano Zampini } 322004708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 322104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 322204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 322304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 322404708bb6SStefano Zampini } else { 3225511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 322604708bb6SStefano Zampini } 322704708bb6SStefano Zampini } 3228a00504b5SStefano Zampini /* extract A_RR */ 3229b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3230a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3231a00504b5SStefano Zampini 3232a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 323316e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3234a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 323516e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 323616e386b8SStefano Zampini } else { 3237a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 3238a00504b5SStefano Zampini } 3239a00504b5SStefano Zampini } else { 3240a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3241a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 3242a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3243a00504b5SStefano Zampini } 3244a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 3245f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 324616e386b8SStefano Zampini } 32473301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 32483301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 32496816873aSStefano Zampini } 3250f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 3251304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 3252304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 3253304d26faSStefano Zampini /* default */ 3254304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 3255e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 3256304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 32579577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 32589577ea80SStefano Zampini if (issbaij) { 32599577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 32609577ea80SStefano Zampini } else { 3261304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 32629577ea80SStefano Zampini } 3263304d26faSStefano Zampini /* Allow user's customization */ 3264304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 3265304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3266304d26faSStefano Zampini } 3267304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3268304d26faSStefano Zampini if (!n_R) { 3269304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 3270304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3271304d26faSStefano Zampini } 32725cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 3273df4d28bfSStefano Zampini /* Reuse solver if it is present */ 3274b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3275df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3276d62866d3SStefano Zampini 3277df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 3278d62866d3SStefano Zampini } 3279304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 3280304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 3281684f6988SStefano Zampini } 3282304d26faSStefano Zampini 3283684f6988SStefano Zampini if (pcbddc->dbg_flag) { 3284684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 32851575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3286684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3287684f6988SStefano Zampini } 3288c7017625SStefano Zampini 3289c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 3290c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 3291c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 3292c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 3293c7017625SStefano Zampini } 3294c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 3295c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 3296c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 3297c7017625SStefano Zampini } 3298c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 3299c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 3300c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 3301c7017625SStefano Zampini } 3302c7017625SStefano Zampini 3303c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 3304c7017625SStefano Zampini if (pcbddc->dbg_flag) { 3305684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 33060fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 33070fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 33080fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 33090fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 33100fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 3311e604994aSStefano 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); 3312c7017625SStefano Zampini if (check_corr[0]) { 3313c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 3314c7017625SStefano Zampini } 3315304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3316304d26faSStefano Zampini } 3317684f6988SStefano Zampini if (neumann) { /* Neumann */ 33180fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 33190fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 33200fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 33210fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 33220fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 3323e604994aSStefano 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); 3324c7017625SStefano Zampini if (check_corr[1]) { 3325c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 3326c7017625SStefano Zampini } 3327304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3328304d26faSStefano Zampini } 3329684f6988SStefano Zampini } 33305cbda25cSStefano Zampini /* free Neumann problem's matrix */ 33315cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3332304d26faSStefano Zampini PetscFunctionReturn(0); 3333304d26faSStefano Zampini } 3334304d26faSStefano Zampini 3335304d26faSStefano Zampini #undef __FUNCT__ 3336ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 333780677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 3338674ae819SStefano Zampini { 3339674ae819SStefano Zampini PetscErrorCode ierr; 3340674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3341be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3342b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 3343674ae819SStefano Zampini 3344674ae819SStefano Zampini PetscFunctionBegin; 3345b334f244SStefano Zampini if (!reuse_solver) { 334680677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 334720c7b377SStefano Zampini } 334880677318SStefano Zampini if (!pcbddc->switch_static) { 334980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 335080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 335180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 335220c7b377SStefano Zampini } 3353b334f244SStefano Zampini if (!reuse_solver) { 335480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 335580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 335620c7b377SStefano Zampini } else { 3357df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3358be83ff47SStefano Zampini 3359df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3360df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 336120c7b377SStefano Zampini } 3362be83ff47SStefano Zampini } else { 336380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 336480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 336580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 336680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 336780677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 336880677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 336980677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 337080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 337180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3372674ae819SStefano Zampini } 3373674ae819SStefano Zampini } 3374b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 337580677318SStefano Zampini if (applytranspose) { 337680677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 337780677318SStefano Zampini } else { 337880677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 337980677318SStefano Zampini } 3380be83ff47SStefano Zampini } else { 3381df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3382be83ff47SStefano Zampini 3383be83ff47SStefano Zampini if (applytranspose) { 3384df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3385be83ff47SStefano Zampini } else { 3386df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3387be83ff47SStefano Zampini } 3388be83ff47SStefano Zampini } 338980677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 339080677318SStefano Zampini if (!pcbddc->switch_static) { 3391b334f244SStefano Zampini if (!reuse_solver) { 339280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 339380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3394be83ff47SStefano Zampini } else { 3395df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3396be83ff47SStefano Zampini 3397df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3398df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3399be83ff47SStefano Zampini } 340080677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 340180677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 340280677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 340380677318SStefano Zampini } 340480677318SStefano Zampini } else { 340580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 340680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 340780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 340880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 340980677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 341080677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 341180677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 341280677318SStefano Zampini } 341380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3417674ae819SStefano Zampini } 3418674ae819SStefano Zampini PetscFunctionReturn(0); 3419674ae819SStefano Zampini } 3420674ae819SStefano Zampini 3421dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 3422674ae819SStefano Zampini #undef __FUNCT__ 3423674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 3424dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 3425674ae819SStefano Zampini { 3426674ae819SStefano Zampini PetscErrorCode ierr; 3427674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3428674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 3429674ae819SStefano Zampini const PetscScalar zero = 0.0; 3430674ae819SStefano Zampini 3431674ae819SStefano Zampini PetscFunctionBegin; 3432dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 34334fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3434dc359a40SStefano Zampini if (applytranspose) { 3435674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 34368eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 3437dc359a40SStefano Zampini } else { 3438674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 3439674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 344015aaf578SStefano Zampini } 34414fee134fSStefano Zampini } else { 34424fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 34434fee134fSStefano Zampini } 3444efc2fbd9SStefano Zampini 3445efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 34464f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3447efc2fbd9SStefano Zampini PetscScalar *array; 34484f1b2e48SStefano Zampini PetscInt j; 3449efc2fbd9SStefano Zampini 3450efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 34514f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 3452efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3453efc2fbd9SStefano Zampini } 3454efc2fbd9SStefano Zampini 345512edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 345612edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 345712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 345812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 345912edc857SStefano Zampini 34609f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 346112edc857SStefano Zampini if (pcbddc->coarse_ksp) { 346251694757SStefano Zampini Mat coarse_mat; 3463964fefecSStefano Zampini Vec rhs,sol; 346451694757SStefano Zampini MatNullSpace nullsp; 346527b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 3466964fefecSStefano Zampini 346727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 346827b6a85dSStefano Zampini PC coarse_pc; 346927b6a85dSStefano Zampini 347027b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 347127b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 347227b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 347327b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 347427b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 347527b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 34763bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 347727b6a85dSStefano Zampini } 347827b6a85dSStefano Zampini } 3479964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 3480964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 348151694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 348251694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 348351694757SStefano Zampini if (nullsp) { 348451694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 348551694757SStefano Zampini } 348612edc857SStefano Zampini if (applytranspose) { 34871f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only) { 34881f4df5f7SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 34892701bc32SStefano Zampini } else { 3490964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 34912701bc32SStefano Zampini } 34922701bc32SStefano Zampini } else { 34931f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 34942701bc32SStefano Zampini PC coarse_pc; 34952701bc32SStefano Zampini 34962701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 34972701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 34983e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 34992701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 350012edc857SStefano Zampini } else { 3501964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 350212edc857SStefano Zampini } 35032701bc32SStefano Zampini } 35041d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 350527b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 350627b6a85dSStefano Zampini PC coarse_pc; 350727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 350827b6a85dSStefano Zampini 350927b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 351027b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 351127b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 35123bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 351327b6a85dSStefano Zampini } 351451694757SStefano Zampini if (nullsp) { 351551694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 351651694757SStefano Zampini } 351712edc857SStefano Zampini } 3518674ae819SStefano Zampini 3519674ae819SStefano Zampini /* Local solution on R nodes */ 35204fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 352180677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 35229f00e9b4SStefano Zampini } 35239f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 35249f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 352512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3526674ae819SStefano Zampini 35274fee134fSStefano Zampini /* Sum contributions from the two levels */ 35284fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3529dc359a40SStefano Zampini if (applytranspose) { 3530dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3531dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3532dc359a40SStefano Zampini } else { 3533674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 35348eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3535dc359a40SStefano Zampini } 3536efc2fbd9SStefano Zampini /* store p0 */ 35374f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3538efc2fbd9SStefano Zampini PetscScalar *array; 35394f1b2e48SStefano Zampini PetscInt j; 3540efc2fbd9SStefano Zampini 3541efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 35424f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 3543efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3544efc2fbd9SStefano Zampini } 35454fee134fSStefano Zampini } else { /* expand the coarse solution */ 35464fee134fSStefano Zampini if (applytranspose) { 35474fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 35484fee134fSStefano Zampini } else { 35494fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 35504fee134fSStefano Zampini } 35514fee134fSStefano Zampini } 3552674ae819SStefano Zampini PetscFunctionReturn(0); 3553674ae819SStefano Zampini } 3554674ae819SStefano Zampini 3555674ae819SStefano Zampini #undef __FUNCT__ 3556674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 355712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 3558674ae819SStefano Zampini { 3559674ae819SStefano Zampini PetscErrorCode ierr; 3560674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 356158da7f69SStefano Zampini PetscScalar *array; 356212edc857SStefano Zampini Vec from,to; 3563674ae819SStefano Zampini 3564674ae819SStefano Zampini PetscFunctionBegin; 356512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 356612edc857SStefano Zampini from = pcbddc->coarse_vec; 356712edc857SStefano Zampini to = pcbddc->vec1_P; 356812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 356912edc857SStefano Zampini Vec tvec; 357058da7f69SStefano Zampini 357158da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 357258da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 357312edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 357458da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 357558da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 357658da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 357712edc857SStefano Zampini } 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 = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3583674ae819SStefano Zampini PetscFunctionReturn(0); 3584674ae819SStefano Zampini } 3585674ae819SStefano Zampini 3586674ae819SStefano Zampini #undef __FUNCT__ 3587674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 358812edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3589674ae819SStefano Zampini { 3590674ae819SStefano Zampini PetscErrorCode ierr; 3591674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 359258da7f69SStefano Zampini PetscScalar *array; 359312edc857SStefano Zampini Vec from,to; 3594674ae819SStefano Zampini 3595674ae819SStefano Zampini PetscFunctionBegin; 359612edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 359712edc857SStefano Zampini from = pcbddc->coarse_vec; 359812edc857SStefano Zampini to = pcbddc->vec1_P; 359912edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 360012edc857SStefano Zampini from = pcbddc->vec1_P; 360112edc857SStefano Zampini to = pcbddc->coarse_vec; 360212edc857SStefano Zampini } 360312edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 360412edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 360512edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 360612edc857SStefano Zampini Vec tvec; 360758da7f69SStefano Zampini 360812edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 360958da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 361058da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 361158da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 361258da7f69SStefano Zampini } 361358da7f69SStefano Zampini } else { 361458da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 361558da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 361612edc857SStefano Zampini } 361712edc857SStefano Zampini } 3618674ae819SStefano Zampini PetscFunctionReturn(0); 3619674ae819SStefano Zampini } 3620674ae819SStefano Zampini 3621984c4197SStefano Zampini /* uncomment for testing purposes */ 3622984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3623674ae819SStefano Zampini #undef __FUNCT__ 3624674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3625674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3626674ae819SStefano Zampini { 3627674ae819SStefano Zampini PetscErrorCode ierr; 3628674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3629674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3630674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3631984c4197SStefano Zampini /* one and zero */ 3632984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3633984c4197SStefano Zampini /* space to store constraints and their local indices */ 36349162d606SStefano Zampini PetscScalar *constraints_data; 36359162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 36369162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 36379162d606SStefano Zampini PetscInt *constraints_n; 3638984c4197SStefano Zampini /* iterators */ 3639b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3640984c4197SStefano Zampini /* BLAS integers */ 3641e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3642e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3643c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3644727cdba6SStefano Zampini /* reuse */ 36450e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 36460e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3647984c4197SStefano Zampini /* change of basis */ 3648b3d85658SStefano Zampini PetscBool qr_needed; 36499162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3650984c4197SStefano Zampini /* auxiliary stuff */ 365164efe560SStefano Zampini PetscInt *nnz,*is_indices; 36528a0068c3SStefano Zampini PetscInt ncc; 3653984c4197SStefano Zampini /* some quantities */ 365445a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3655a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3656984c4197SStefano Zampini 3657674ae819SStefano Zampini PetscFunctionBegin; 36588e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 36598e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 36608e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 366116909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 3662088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3663088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 36640e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 36650e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 36660e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 36670e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 36680e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3669088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3670cf5a6209SStefano Zampini 3671cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 36729162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3673cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3674cf5a6209SStefano Zampini const Vec *nearnullvecs; 3675cf5a6209SStefano Zampini Vec *localnearnullsp; 3676cf5a6209SStefano Zampini PetscScalar *array; 3677cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3678cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3679674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3680b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3681674ae819SStefano Zampini PetscScalar *work; 3682674ae819SStefano Zampini PetscReal *singular_vals; 3683674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3684674ae819SStefano Zampini PetscReal *rwork; 3685674ae819SStefano Zampini #endif 3686674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3687674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3688674ae819SStefano Zampini #else 3689964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3690964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3691674ae819SStefano Zampini #endif 3692674ae819SStefano Zampini 3693674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3694d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3695e4d548c7SStefano Zampini /* print some info */ 36961f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 3697e4d548c7SStefano Zampini PetscInt nv; 3698e4d548c7SStefano Zampini 3699e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 3700e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 3701e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3702e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3703e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3704e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 3705e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 3706e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3707e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3708e4d548c7SStefano Zampini } 3709e4d548c7SStefano Zampini 3710d06fc5fdSStefano Zampini /* free unneeded index sets */ 3711d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3712d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3713674ae819SStefano Zampini } 3714d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3715d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3716d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3717d06fc5fdSStefano Zampini } 3718d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3719d06fc5fdSStefano Zampini n_ISForEdges = 0; 3720d06fc5fdSStefano Zampini } 3721d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3722d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3723d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3724d06fc5fdSStefano Zampini } 3725d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3726d06fc5fdSStefano Zampini n_ISForFaces = 0; 3727d06fc5fdSStefano Zampini } 372870022509SStefano Zampini 3729674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3730674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3731674ae819SStefano Zampini if (nearnullsp) { 3732674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3733f4ddd8eeSStefano Zampini /* remove any stored info */ 3734f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3735f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3736f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3737f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3738f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3739473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3740f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3741f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3742f4ddd8eeSStefano Zampini } 3743984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3744984c4197SStefano Zampini nnsp_size = 0; 3745674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3746674ae819SStefano Zampini } 3747984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3748984c4197SStefano Zampini max_constraints = nnsp_size; 3749984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3750984c4197SStefano Zampini 3751674ae819SStefano Zampini /* 3752674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 37539162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 37549162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 37559162d606SStefano Zampini There can be multiple constraints per connected component 3756674ae819SStefano Zampini */ 3757674ae819SStefano Zampini n_vertices = 0; 3758674ae819SStefano Zampini if (ISForVertices) { 3759674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3760674ae819SStefano Zampini } 37619162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 37629162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 37639162d606SStefano Zampini 37649162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 37659162d606SStefano Zampini total_counts *= max_constraints; 3766674ae819SStefano Zampini total_counts += n_vertices; 37674641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 37689162d606SStefano Zampini 3769674ae819SStefano Zampini total_counts = 0; 3770674ae819SStefano Zampini max_size_of_constraint = 0; 3771674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 37729162d606SStefano Zampini IS used_is; 3773674ae819SStefano Zampini if (i<n_ISForEdges) { 37749162d606SStefano Zampini used_is = ISForEdges[i]; 3775674ae819SStefano Zampini } else { 37769162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3777674ae819SStefano Zampini } 37789162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3779674ae819SStefano Zampini total_counts += j; 3780674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3781674ae819SStefano Zampini } 37829162d606SStefano 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); 37839162d606SStefano Zampini 3784984c4197SStefano Zampini /* get local part of global near null space vectors */ 3785785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3786984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3787984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3788e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3789e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3790984c4197SStefano Zampini } 3791674ae819SStefano Zampini 3792242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3793242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3794a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3795242a89d7SStefano Zampini 3796984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3797a773dcb8SStefano Zampini if (!skip_lapack) { 3798674ae819SStefano Zampini PetscScalar temp_work; 3799911cabfeSStefano Zampini 3800674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3801984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3802785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3803785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3804785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3805674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3806785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3807674ae819SStefano Zampini #endif 3808674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3809c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3810c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3811674ae819SStefano Zampini lwork = -1; 3812674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3813674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3814c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3815674ae819SStefano Zampini #else 3816c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3817674ae819SStefano Zampini #endif 3818674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3819984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3820674ae819SStefano Zampini #else /* on missing GESVD */ 3821674ae819SStefano Zampini /* SVD */ 3822674ae819SStefano Zampini PetscInt max_n,min_n; 3823674ae819SStefano Zampini max_n = max_size_of_constraint; 3824984c4197SStefano Zampini min_n = max_constraints; 3825984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3826674ae819SStefano Zampini min_n = max_size_of_constraint; 3827984c4197SStefano Zampini max_n = max_constraints; 3828674ae819SStefano Zampini } 3829785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3830674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3831785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3832674ae819SStefano Zampini #endif 3833674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3834674ae819SStefano Zampini lwork = -1; 3835e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3836e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3837b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3838674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3839674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 38409162d606SStefano 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)); 3841674ae819SStefano Zampini #else 38429162d606SStefano 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)); 3843674ae819SStefano Zampini #endif 3844674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3845984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3846984c4197SStefano Zampini #endif /* on missing GESVD */ 3847674ae819SStefano Zampini /* Allocate optimal workspace */ 3848674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3849854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3850674ae819SStefano Zampini } 3851674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3852674ae819SStefano Zampini total_counts = 0; 38539162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 38549162d606SStefano Zampini constraints_data_ptr[0] = 0; 3855674ae819SStefano Zampini /* vertices */ 38569162d606SStefano Zampini if (n_vertices) { 3857674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 38589162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3859674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 38609162d606SStefano Zampini constraints_n[total_counts] = 1; 38619162d606SStefano Zampini constraints_data[total_counts] = 1.0; 38629162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 38639162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3864674ae819SStefano Zampini total_counts++; 3865674ae819SStefano Zampini } 3866674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3867674ae819SStefano Zampini n_vertices = total_counts; 3868674ae819SStefano Zampini } 3869984c4197SStefano Zampini 3870674ae819SStefano Zampini /* edges and faces */ 38719162d606SStefano Zampini total_counts_cc = total_counts; 3872911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 38739162d606SStefano Zampini IS used_is; 38749162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 38759162d606SStefano Zampini 3876911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 38779162d606SStefano Zampini used_is = ISForEdges[ncc]; 3878984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3879674ae819SStefano Zampini } else { 38809162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3881984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3882674ae819SStefano Zampini } 3883674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 38849162d606SStefano Zampini 38859162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 38869162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3887984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3888984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3889674ae819SStefano Zampini if (nnsp_has_cnst) { 38905b08dc53SStefano Zampini PetscScalar quad_value; 38919162d606SStefano Zampini 38929162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 38939162d606SStefano Zampini idxs_copied = PETSC_TRUE; 38949162d606SStefano Zampini 3895a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3896674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3897a773dcb8SStefano Zampini } else { 3898a773dcb8SStefano Zampini quad_value = 1.0; 3899a773dcb8SStefano Zampini } 3900674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 39019162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3902674ae819SStefano Zampini } 39039162d606SStefano Zampini temp_constraints++; 3904674ae819SStefano Zampini total_counts++; 3905674ae819SStefano Zampini } 3906674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3907984c4197SStefano Zampini PetscReal real_value; 39089162d606SStefano Zampini PetscScalar *ptr_to_data; 39099162d606SStefano Zampini 3910984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 39119162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3912674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 39139162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3914674ae819SStefano Zampini } 3915984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3916984c4197SStefano Zampini /* check if array is null on the connected component */ 3917e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39189162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 39195b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3920674ae819SStefano Zampini temp_constraints++; 3921674ae819SStefano Zampini total_counts++; 39229162d606SStefano Zampini if (!idxs_copied) { 39239162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 39249162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3925674ae819SStefano Zampini } 3926674ae819SStefano Zampini } 39279162d606SStefano Zampini } 39289162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 392945a1bb75SStefano Zampini valid_constraints = temp_constraints; 3930eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3931a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 39329162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 39339162d606SStefano Zampini 39349162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3935a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39369162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3937a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 39389162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3939a773dcb8SStefano Zampini } else { /* perform SVD */ 3940984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 39419162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3942674ae819SStefano Zampini 3943674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3944984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3945984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3946984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3947984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3948984c4197SStefano Zampini from that computed using LAPACKgesvd 3949984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3950984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3951984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3952674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3953e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3954984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3955674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3956674ae819SStefano Zampini for (k=0;k<j+1;k++) { 39579162d606SStefano 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)); 3958674ae819SStefano Zampini } 3959674ae819SStefano Zampini } 3960e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3961e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3962e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3963674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3964c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3965674ae819SStefano Zampini #else 3966c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3967674ae819SStefano Zampini #endif 3968674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3969984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3970984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3971674ae819SStefano Zampini j = 0; 3972984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3973674ae819SStefano Zampini total_counts = total_counts-j; 397445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3975e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3976c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3977c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3978c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3979c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3980c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3981c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3982674ae819SStefano Zampini if (j<temp_constraints) { 3983984c4197SStefano Zampini PetscInt ii; 3984984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3985674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39869162d606SStefano 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)); 3987674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3988984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3989674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 39909162d606SStefano 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]; 3991674ae819SStefano Zampini } 3992674ae819SStefano Zampini } 3993674ae819SStefano Zampini } 3994674ae819SStefano Zampini #else /* on missing GESVD */ 3995e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3996e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3997b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3998674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3999674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 40009162d606SStefano 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)); 4001674ae819SStefano Zampini #else 40029162d606SStefano 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)); 4003674ae819SStefano Zampini #endif 4004984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 4005674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4006984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 4007e310c8b4SStefano Zampini k = temp_constraints; 4008e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 4009674ae819SStefano Zampini j = 0; 4010e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 401145a1bb75SStefano Zampini valid_constraints = k-j; 4012911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 4013984c4197SStefano Zampini #endif /* on missing GESVD */ 4014674ae819SStefano Zampini } 4015a773dcb8SStefano Zampini } 40169162d606SStefano Zampini /* update pointers information */ 40179162d606SStefano Zampini if (valid_constraints) { 40189162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 40199162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 40209162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 40219162d606SStefano Zampini /* set change_of_basis flag */ 402245a1bb75SStefano Zampini if (boolforchange) { 4023b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 40249162d606SStefano Zampini } 4025b3d85658SStefano Zampini total_counts_cc++; 402645a1bb75SStefano Zampini } 402745a1bb75SStefano Zampini } 4028984c4197SStefano Zampini /* free workspace */ 40298f1c130eSStefano Zampini if (!skip_lapack) { 4030984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4031984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4032984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 4033984c4197SStefano Zampini #endif 4034984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 4035984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4036984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 4037984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 4038984c4197SStefano Zampini #endif 4039984c4197SStefano Zampini } 4040984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4041984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 4042984c4197SStefano Zampini } 4043984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 4044cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 4045cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4046cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4047cf5a6209SStefano Zampini } 4048cf5a6209SStefano Zampini if (n_ISForFaces) { 4049cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4050cf5a6209SStefano Zampini } 4051cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4052cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4053cf5a6209SStefano Zampini } 4054cf5a6209SStefano Zampini if (n_ISForEdges) { 4055cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4056cf5a6209SStefano Zampini } 4057cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 405808122e43SStefano Zampini } else { 405908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4060984c4197SStefano Zampini 406108122e43SStefano Zampini total_counts = 0; 406208122e43SStefano Zampini n_vertices = 0; 4063d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 4064d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 406508122e43SStefano Zampini } 406608122e43SStefano Zampini max_constraints = 0; 40679162d606SStefano Zampini total_counts_cc = 0; 406808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 406908122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 40709162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 407108122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 407208122e43SStefano Zampini } 40739162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 40749162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 40759162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 40769162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 407774d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 40789162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 40799162d606SStefano Zampini total_counts_cc = 0; 40809162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 40819162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 40829162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 408308122e43SStefano Zampini } 408408122e43SStefano Zampini } 40859162d606SStefano Zampini #if 0 40869162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 40879162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 40889162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 40899162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 40909162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 40919162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 40929162d606SStefano Zampini } 40939162d606SStefano Zampini printf("\n"); 40949162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 40959162d606SStefano Zampini } 40961b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 40978bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 40981b968477SStefano Zampini } 40991b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 41008bec7fa6SStefano 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]); 41011b968477SStefano Zampini } 410208122e43SStefano Zampini #endif 410308122e43SStefano Zampini 41048bec7fa6SStefano Zampini max_size_of_constraint = 0; 41059162d606SStefano 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]); 41069162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 410708122e43SStefano Zampini /* Change of basis */ 4108b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 410908122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 411008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 411108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 4112b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 411308122e43SStefano Zampini } 411408122e43SStefano Zampini } 411508122e43SStefano Zampini } 411608122e43SStefano Zampini } 4117984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 41184f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 411908122e43SStefano Zampini 41209162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 41219162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 41226c4ed002SBarry 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); 4123674ae819SStefano Zampini 4124674ae819SStefano Zampini /* Create constraint matrix */ 4125674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 412616f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 4127984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 4128984c4197SStefano Zampini 4129984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 4130a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 4131a717540cSStefano Zampini qr_needed = PETSC_FALSE; 413274d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 4133984c4197SStefano Zampini total_primal_vertices=0; 4134b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 41359162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 41369162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 413772b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 41389162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 4139b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 414064efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 41419162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 41429162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 4143a717540cSStefano Zampini } 4144b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 414591af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 4146a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 4147a717540cSStefano Zampini qr_needed = PETSC_TRUE; 4148a717540cSStefano Zampini } 4149fa434743SStefano Zampini } else { 4150b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 4151fa434743SStefano Zampini } 4152a717540cSStefano Zampini } 4153b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 4154b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 4155674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 415670022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4157b3d85658SStefano Zampini 41584f1b2e48SStefano 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); 41590e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 41600e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 4161984c4197SStefano Zampini 4162984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 416374d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 4164785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 4165984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 416674d5cdf7SStefano Zampini 4167984c4197SStefano Zampini j = total_primal_vertices; 416874d5cdf7SStefano Zampini total_counts = total_primal_vertices; 4169b3d85658SStefano Zampini cum = total_primal_vertices; 41709162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 41714641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 4172b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 4173b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 4174b3d85658SStefano Zampini cum++; 41759162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 417674d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 417774d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 417874d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 417974d5cdf7SStefano Zampini } 41809162d606SStefano Zampini j += constraints_n[i]; 4181674ae819SStefano Zampini } 4182674ae819SStefano Zampini } 4183674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 4184674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 4185088faed8SStefano Zampini 4186674ae819SStefano Zampini /* set values in constraint matrix */ 4187984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 41880e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4189674ae819SStefano Zampini } 4190984c4197SStefano Zampini total_counts = total_primal_vertices; 41919162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 41924641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 41939162d606SStefano Zampini PetscInt *cols; 41949162d606SStefano Zampini 41959162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 41969162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 41979162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 41989162d606SStefano Zampini PetscInt row = total_counts+k; 41999162d606SStefano Zampini PetscScalar *vals; 42009162d606SStefano Zampini 42019162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 42029162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 42039162d606SStefano Zampini } 42049162d606SStefano Zampini total_counts += constraints_n[i]; 4205674ae819SStefano Zampini } 4206674ae819SStefano Zampini } 4207674ae819SStefano Zampini /* assembling */ 4208674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4209674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4210088faed8SStefano Zampini 4211984c4197SStefano Zampini /* 42126a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4213984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 4214f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 4215984c4197SStefano Zampini */ 4216674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 4217674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 4218026de310SStefano Zampini /* dual and primal dofs on a single cc */ 4219984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 4220984c4197SStefano Zampini /* working stuff for GEQRF */ 422181d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 4222984c4197SStefano Zampini PetscBLASInt lqr_work; 4223984c4197SStefano Zampini /* working stuff for UNGQR */ 4224984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 4225984c4197SStefano Zampini PetscBLASInt lgqr_work; 4226984c4197SStefano Zampini /* working stuff for TRTRS */ 4227984c4197SStefano Zampini PetscScalar *trs_rhs; 42283f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 4229984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 4230984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 4231984c4197SStefano Zampini PetscScalar *start_vals; 4232984c4197SStefano Zampini /* working stuff for values insertion */ 42334641a718SStefano Zampini PetscBT is_primal; 423464efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 4235906d46d4SStefano Zampini /* matrix sizes */ 4236906d46d4SStefano Zampini PetscInt global_size,local_size; 4237906d46d4SStefano Zampini /* temporary change of basis */ 4238906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 4239cf5a6209SStefano Zampini /* extra space for debugging */ 4240cf5a6209SStefano Zampini PetscScalar *dbg_work; 4241984c4197SStefano Zampini 4242906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 4243906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 424416f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 4245bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 4246906d46d4SStefano Zampini /* nonzeros for local mat */ 4247bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 42481dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4249bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 42501dd7afcfSStefano Zampini } else { 42511dd7afcfSStefano Zampini const PetscInt *ii; 42521dd7afcfSStefano Zampini PetscInt n; 42531dd7afcfSStefano Zampini PetscBool flg_row; 42541dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 42551dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 42561dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 42571dd7afcfSStefano Zampini } 42589162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 4259a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 42609162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 4261a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 42629162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 4263a717540cSStefano Zampini } else { 42649162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 42659162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 4266a717540cSStefano Zampini } 4267a717540cSStefano Zampini } 4268a717540cSStefano Zampini } 4269906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 4270bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 42711dd7afcfSStefano Zampini /* Set interior change in the matrix */ 42721dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4273bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 4274906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 4275a717540cSStefano Zampini } 42761dd7afcfSStefano Zampini } else { 42771dd7afcfSStefano Zampini const PetscInt *ii,*jj; 42781dd7afcfSStefano Zampini PetscScalar *aa; 42791dd7afcfSStefano Zampini PetscInt n; 42801dd7afcfSStefano Zampini PetscBool flg_row; 42811dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 42821dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 42831dd7afcfSStefano Zampini for (i=0;i<n;i++) { 42841dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 42851dd7afcfSStefano Zampini } 42861dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 42871dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 42881dd7afcfSStefano Zampini } 4289a717540cSStefano Zampini 4290a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4291a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4292a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4293a717540cSStefano Zampini } 4294a717540cSStefano Zampini 4295a717540cSStefano Zampini 4296a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 4297a717540cSStefano Zampini /* 4298a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 4299a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 4300a717540cSStefano Zampini 4301a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 4302a717540cSStefano Zampini 4303a6b551f4SStefano 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) 4304a6b551f4SStefano Zampini 4305a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 4306a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 4307a717540cSStefano Zampini | ... | 4308a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 4309a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 4310a717540cSStefano Zampini 4311a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 4312a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 4313a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 4314a6b551f4SStefano Zampini 4315a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 4316a717540cSStefano Zampini */ 4317a717540cSStefano Zampini if (qr_needed) { 4318984c4197SStefano Zampini /* space to store Q */ 4319854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 4320984c4197SStefano Zampini /* first we issue queries for optimal work */ 43213f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 43223f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 43233f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4324984c4197SStefano Zampini lqr_work = -1; 43253f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 4326984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 4327984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 4328785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 4329984c4197SStefano Zampini lgqr_work = -1; 43303f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 43313f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 43323f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 43333f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 43343f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 43353f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 4336984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 4337984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 4338785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 4339984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 4340785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 4341984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 4342785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 4343a717540cSStefano Zampini /* allocating workspace for check */ 4344a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4345cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 4346a717540cSStefano Zampini } 4347a717540cSStefano Zampini } 4348984c4197SStefano Zampini /* array to store whether a node is primal or not */ 43494641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 4350473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 43510e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 43526c4ed002SBarry 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); 435339e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 435439e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 435539e2fb2aSStefano Zampini } 435639e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 4357984c4197SStefano Zampini 4358a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 43599162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 43609162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 43614641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 4362984c4197SStefano Zampini /* get constraint info */ 43639162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 4364984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 4365984c4197SStefano Zampini 4366984c4197SStefano Zampini if (pcbddc->dbg_flag) { 43679162d606SStefano 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); 4368674ae819SStefano Zampini } 4369984c4197SStefano Zampini 4370fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 4371a717540cSStefano Zampini 4372a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 4373a717540cSStefano Zampini if (pcbddc->dbg_flag) { 43749162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4375a717540cSStefano Zampini } 4376984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 43779162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4378984c4197SStefano Zampini 4379984c4197SStefano Zampini /* compute QR decomposition of constraints */ 43803f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 43813f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 43823f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4383674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43843f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 4385984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 4386674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4387984c4197SStefano Zampini 4388984c4197SStefano Zampini /* explictly compute R^-T */ 4389984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 4390984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 43913f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 43923f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 43933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 43943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 4395984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43963f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 4397984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 4398984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4399984c4197SStefano Zampini 4400a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 44013f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 44023f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 44033f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 44043f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4405984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 44063f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 4407984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 4408984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4409984c4197SStefano Zampini 4410984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 4411984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 4412984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 44133f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 44143f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 44153f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 44163f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 44173f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 44183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 4419984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 44209162d606SStefano 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)); 4421984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 44229162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4423984c4197SStefano Zampini 4424984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 44259162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 4426984c4197SStefano Zampini /* insert cols for primal dofs */ 4427984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 4428984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 44299162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4430906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4431984c4197SStefano Zampini } 4432984c4197SStefano Zampini /* insert cols for dual dofs */ 4433984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 44349162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 4435984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 44369162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4437906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4438984c4197SStefano Zampini j++; 4439674ae819SStefano Zampini } 4440674ae819SStefano Zampini } 4441984c4197SStefano Zampini 4442984c4197SStefano Zampini /* check change of basis */ 4443984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4444984c4197SStefano Zampini PetscInt ii,jj; 4445984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 4446c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 4447c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4448c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 4449c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4450c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 4451c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 4452984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4453cf5a6209SStefano 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)); 4454984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4455984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4456984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4457cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 4458cf5a6209SStefano 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; 4459674ae819SStefano Zampini } 4460674ae819SStefano Zampini } 4461984c4197SStefano Zampini if (!valid_qr) { 446222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 4463984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4464984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4465cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 4466cf5a6209SStefano 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])); 4467674ae819SStefano Zampini } 4468cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 4469cf5a6209SStefano 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])); 4470984c4197SStefano Zampini } 4471984c4197SStefano Zampini } 4472984c4197SStefano Zampini } 4473674ae819SStefano Zampini } else { 447422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 4475674ae819SStefano Zampini } 4476674ae819SStefano Zampini } 4477a717540cSStefano Zampini } else { /* simple transformation block */ 4478a717540cSStefano Zampini PetscInt row,col; 4479a6b551f4SStefano Zampini PetscScalar val,norm; 4480a6b551f4SStefano Zampini 4481a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 44829162d606SStefano 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)); 4483a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 44849162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 44859162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4486bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 44879162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 4488906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 44899162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 4490a717540cSStefano Zampini } else { 4491a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 44929162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4493a717540cSStefano Zampini if (row != col) { 44949162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 4495a717540cSStefano Zampini } else { 44969162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 4497a717540cSStefano Zampini } 4498906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 4499a717540cSStefano Zampini } 4500a717540cSStefano Zampini } 4501a717540cSStefano Zampini } 450298a51de6SStefano Zampini if (pcbddc->dbg_flag) { 450322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 4504a717540cSStefano Zampini } 4505674ae819SStefano Zampini } 4506984c4197SStefano Zampini } else { 4507984c4197SStefano Zampini if (pcbddc->dbg_flag) { 45089162d606SStefano 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); 4509674ae819SStefano Zampini } 4510674ae819SStefano Zampini } 4511674ae819SStefano Zampini } 4512a717540cSStefano Zampini 4513a717540cSStefano Zampini /* free workspace */ 4514a717540cSStefano Zampini if (qr_needed) { 4515984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4516cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 4517984c4197SStefano Zampini } 4518984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 4519984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 4520984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 4521984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 4522984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 4523674ae819SStefano Zampini } 4524a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 4525906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4526906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4527906d46d4SStefano Zampini 4528906d46d4SStefano Zampini /* assembling of global change of variable */ 452988c03ad3SStefano Zampini if (!pcbddc->fake_change) { 4530bbb9e6c6SStefano Zampini Mat tmat; 453116f15bc4SStefano Zampini PetscInt bs; 453216f15bc4SStefano Zampini 4533906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4534906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4535bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4536bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 4537bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4538bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 453916f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 454016f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 4541906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4542bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 4543bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4544bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4545bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4546bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4547e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4548e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4549bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 4550bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 455188c03ad3SStefano Zampini 4552906d46d4SStefano Zampini /* check */ 4553906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4554906d46d4SStefano Zampini PetscReal error; 4555906d46d4SStefano Zampini Vec x,x_change; 4556906d46d4SStefano Zampini 4557906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 4558906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 4559906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 4560906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 4561e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4562e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4563bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4564e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4565e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4566906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4567906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4568906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4569906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4570bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4571906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4572906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4573906d46d4SStefano Zampini } 4574b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4575b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4576b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4577bf3a8328SStefano Zampini 4578bf3a8328SStefano Zampini if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) { 4579bf3a8328SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints");CHKERRQ(ierr); 4580bf3a8328SStefano Zampini } 4581b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 4582ac632422SStefano Zampini Mat S_new,tmat; 4583bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 4584bbb9e6c6SStefano Zampini 4585bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 45866816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4587bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4588bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 4589bf3a8328SStefano Zampini IS is_V; 4590b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4591b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4592b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4593b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4594b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4595bf3a8328SStefano Zampini } 4596bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4597ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4598b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4599ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4600bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4601bf3a8328SStefano Zampini const PetscScalar *array; 4602bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 4603bf3a8328SStefano Zampini PetscInt i,n_V; 4604bf3a8328SStefano Zampini 4605b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4606b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4607b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4608b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4609b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4610b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4611b087196eSStefano Zampini PetscScalar val; 4612b087196eSStefano Zampini PetscInt idx; 4613b087196eSStefano Zampini 4614b087196eSStefano Zampini idx = idxs_V[i]; 4615b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4616b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4617b087196eSStefano Zampini } 4618b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4619b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4620bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4621bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4622bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4623bf3a8328SStefano Zampini } 4624ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4625ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4626ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4627ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4628b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4629ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4630bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4631b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4632bf3a8328SStefano Zampini } 4633ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4634ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4635ac632422SStefano Zampini } 4636b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 463788c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4638b96c3477SStefano Zampini } 4639c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 4640b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 4641c9db6a07SStefano Zampini PetscInt i; 4642c9db6a07SStefano Zampini 4643c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4644c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 4645c9db6a07SStefano Zampini } 4646c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 4647c9db6a07SStefano Zampini } 4648b96c3477SStefano Zampini } 464916909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 465016909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 465116909a7fSStefano Zampini } else { 4652906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 465316909a7fSStefano Zampini } 46541dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 465527b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 465672b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 465772b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 465872b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 465972b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 466072b8c272SStefano Zampini } 46611dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 466227b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 4663b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4664b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4665906d46d4SStefano Zampini } else { 46661dd7afcfSStefano Zampini Mat benign_global = NULL; 466727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 46681dd7afcfSStefano Zampini Mat tmat; 46691dd7afcfSStefano Zampini 46701dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 46711dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 46721dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 46731dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 46741dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 46751dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 46761dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46771dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46781dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 46791dd7afcfSStefano Zampini if (pcbddc->benign_change) { 46801dd7afcfSStefano Zampini Mat M; 46811dd7afcfSStefano Zampini 46821dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 46831dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 46841dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 46851dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4686906d46d4SStefano Zampini } else { 46871dd7afcfSStefano Zampini Mat eye; 46881dd7afcfSStefano Zampini PetscScalar *array; 46891dd7afcfSStefano Zampini 46901dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 46911dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 46921dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 46931dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 4694906d46d4SStefano Zampini } 46951dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 46961dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46971dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46981dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 46991dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 47001dd7afcfSStefano Zampini } 47011dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 47021dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 47031dd7afcfSStefano Zampini } 47041dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 47051dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 47061dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 470727b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 47081dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 47091dd7afcfSStefano Zampini } 47101dd7afcfSStefano Zampini } 471116909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 471216909a7fSStefano Zampini IS is_global; 471316909a7fSStefano Zampini const PetscInt *gidxs; 471416909a7fSStefano Zampini 471516909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 471616909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 471716909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 471816909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 471916909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 472016909a7fSStefano Zampini } 47211dd7afcfSStefano Zampini } 47221dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 47231dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 4724b9b85e73SStefano Zampini } 4725a717540cSStefano Zampini 472672b8c272SStefano Zampini if (!pcbddc->fake_change) { 47274f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 47284f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 47294f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 47304f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4731019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4732019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4733019a44ceSStefano Zampini pcbddc->local_primal_size++; 4734019a44ceSStefano Zampini } 4735019a44ceSStefano Zampini 4736019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4737727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4738727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 47399f47a83aSStefano 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); 4740c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 47410e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 47429f47a83aSStefano 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); 4743727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4744727cdba6SStefano Zampini } 47450e6343abSStefano Zampini } 4746727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4747b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 474872b8c272SStefano Zampini } 474972b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4750727cdba6SStefano Zampini 4751a717540cSStefano Zampini /* flush dbg viewer */ 4752b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4753b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4754b8ffe317SStefano Zampini } 4755a717540cSStefano Zampini 4756e310c8b4SStefano Zampini /* free workspace */ 4757a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 47584641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 475908122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 47609162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 47619162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 476208122e43SStefano Zampini } else { 47639162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 47649162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 47659162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 476608122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 476708122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 47689162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 47699162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 477008122e43SStefano Zampini } 4771674ae819SStefano Zampini PetscFunctionReturn(0); 4772674ae819SStefano Zampini } 4773674ae819SStefano Zampini 4774674ae819SStefano Zampini #undef __FUNCT__ 4775674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4776674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4777674ae819SStefano Zampini { 4778674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4779674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4780674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 478114f95afaSStefano Zampini PetscInt ierr,i,N; 4782674ae819SStefano Zampini 4783674ae819SStefano Zampini PetscFunctionBegin; 47848e61c736SStefano Zampini /* Reset previously computed graph */ 47858e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4786674ae819SStefano Zampini /* Init local Graph struct */ 47877fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 47883bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4789674ae819SStefano Zampini 4790575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 47915099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 47925099eff2SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid size of local CSR graph! Found %d, expected %d\n",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 4793575ad6abSStefano Zampini } 47949577ea80SStefano Zampini 4795674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 4796d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 47974d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 47984d379d7bSStefano Zampini PetscInt nvtxs; 4799e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4800674ae819SStefano Zampini 48012fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 48022fffb893SStefano Zampini if (flg_row) { 48034d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4804b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 48052fffb893SStefano Zampini } 48062fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4807674ae819SStefano Zampini } 48089b28b941SStefano Zampini if (pcbddc->dbg_flag) { 48099b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4810674ae819SStefano Zampini } 4811674ae819SStefano Zampini 4812674ae819SStefano Zampini /* Setup of Graph */ 48134b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 481414f95afaSStefano 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); 4815674ae819SStefano Zampini 48164f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 48174f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 48184f1b2e48SStefano Zampini PetscInt *local_subs; 48194f1b2e48SStefano Zampini 48204f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 48214f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 48224f1b2e48SStefano Zampini const PetscInt *idxs; 48234f1b2e48SStefano Zampini PetscInt nl,j; 48244f1b2e48SStefano Zampini 48254f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 48264f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 48274f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 48284f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 48294f1b2e48SStefano Zampini } 48304f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 48314f1b2e48SStefano Zampini } 48324f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 48334f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 48344f1b2e48SStefano Zampini } 48354f1b2e48SStefano Zampini 4836674ae819SStefano Zampini /* Graph's connected components analysis */ 4837674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4838674ae819SStefano Zampini PetscFunctionReturn(0); 4839674ae819SStefano Zampini } 4840674ae819SStefano Zampini 4841dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 4842674ae819SStefano Zampini #undef __FUNCT__ 4843674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 4844dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 4845674ae819SStefano Zampini { 4846dc456d91SStefano Zampini PetscSF sf; 4847dc456d91SStefano Zampini PetscLayout map; 4848dc456d91SStefano Zampini const PetscInt *idxs; 4849dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4850dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4851dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4852dc456d91SStefano Zampini PetscMPIInt commsize; 4853674ae819SStefano Zampini PetscBool first_found; 4854674ae819SStefano Zampini PetscErrorCode ierr; 4855674ae819SStefano Zampini 4856674ae819SStefano Zampini PetscFunctionBegin; 4857dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4858dc456d91SStefano Zampini if (subset_mult) { 4859dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4860dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4861dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4862674ae819SStefano Zampini } 4863dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4864dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4865dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4866dc456d91SStefano Zampini for (i=0;i<n;i++) { 4867dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4868dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4869674ae819SStefano Zampini } 4870dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4871b2566f29SBarry Smith ierr = MPIU_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4872dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4873dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4874dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4875dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4876dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4877dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4878dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4879dc456d91SStefano Zampini 4880dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4881dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4882dc456d91SStefano Zampini if (subset_mult) { 4883dc456d91SStefano Zampini const PetscInt* idxs_mult; 4884dc456d91SStefano Zampini 4885dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4886dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4887dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4888674ae819SStefano Zampini } else { 4889dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4890674ae819SStefano Zampini } 4891dc456d91SStefano Zampini /* local size of new subset */ 4892dc456d91SStefano Zampini n_n = 0; 4893dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4894dc456d91SStefano Zampini 4895dc456d91SStefano Zampini /* global indexes in layout */ 4896dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4897dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4898dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4899dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4900dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4901dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4902dc456d91SStefano Zampini 4903dc456d91SStefano Zampini /* reduce from leaves to roots */ 4904dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 490564a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 490664a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4907dc456d91SStefano Zampini 4908dc456d91SStefano Zampini /* count indexes in local part of layout */ 4909674ae819SStefano Zampini nlocals = 0; 4910674ae819SStefano Zampini first_index = -1; 4911674ae819SStefano Zampini first_found = PETSC_FALSE; 4912dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4913dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4914674ae819SStefano Zampini first_found = PETSC_TRUE; 4915674ae819SStefano Zampini first_index = i; 4916674ae819SStefano Zampini } 4917dc456d91SStefano Zampini nlocals += root_data[i]; 4918674ae819SStefano Zampini } 4919dc456d91SStefano Zampini 4920dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 49215fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4922dc456d91SStefano Zampini start = 0; 492364a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 49245fa240b1SStefano Zampini #else 492564a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 49265fa240b1SStefano Zampini start = start-nlocals; 49275fa240b1SStefano Zampini #endif 49285fa240b1SStefano Zampini 4929dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4930dc456d91SStefano Zampini *N_n = start + nlocals; 4931dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4932dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4933674ae819SStefano Zampini } 49345fa240b1SStefano Zampini 49355fa240b1SStefano Zampini /* adapt root data with cumulative */ 4936674ae819SStefano Zampini if (first_found) { 4937dc456d91SStefano Zampini PetscInt old_index; 4938dc456d91SStefano Zampini 4939dc456d91SStefano Zampini root_data[first_index] += start; 4940674ae819SStefano Zampini old_index = first_index; 4941dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4942dc456d91SStefano Zampini if (root_data[i]) { 4943dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4944674ae819SStefano Zampini old_index = i; 4945674ae819SStefano Zampini } 4946674ae819SStefano Zampini } 4947674ae819SStefano Zampini } 4948dc456d91SStefano Zampini 4949dc456d91SStefano Zampini /* from roots to leaves */ 4950dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4951dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4952dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4953dc456d91SStefano Zampini 4954dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4955dc456d91SStefano Zampini if (subset_mult) { 4956dc456d91SStefano Zampini const PetscInt* idxs_mult; 4957dc456d91SStefano Zampini PetscInt cum; 4958dc456d91SStefano Zampini 4959dc456d91SStefano Zampini cum = 0; 4960dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4961dc456d91SStefano Zampini for (i=0;i<n;i++) { 4962dc456d91SStefano Zampini PetscInt j; 4963dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4964674ae819SStefano Zampini } 4965dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4966674ae819SStefano Zampini } else { 4967dc456d91SStefano Zampini for (i=0;i<n;i++) { 4968dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4969674ae819SStefano Zampini } 4970674ae819SStefano Zampini } 4971dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4972dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4973674ae819SStefano Zampini PetscFunctionReturn(0); 4974674ae819SStefano Zampini } 49759a7d3425SStefano Zampini 4976669cc0f4SStefano Zampini /* this implements stabilized Gram-Schmidt */ 49779a7d3425SStefano Zampini #undef __FUNCT__ 49789a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 49799a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 49809a7d3425SStefano Zampini { 49819a7d3425SStefano Zampini PetscInt i,j; 49829a7d3425SStefano Zampini PetscScalar *alphas; 49839a7d3425SStefano Zampini PetscErrorCode ierr; 49849a7d3425SStefano Zampini 49859a7d3425SStefano Zampini PetscFunctionBegin; 4986785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 49879a7d3425SStefano Zampini for (i=0;i<n;i++) { 49889a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 4989669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 4990669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 4991669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 49929a7d3425SStefano Zampini } 49939a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 49949a7d3425SStefano Zampini PetscFunctionReturn(0); 49959a7d3425SStefano Zampini } 49969a7d3425SStefano Zampini 4997e7931f94SStefano Zampini #undef __FUNCT__ 499870cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 499957de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 5000e7931f94SStefano Zampini { 500157de7509SStefano Zampini Mat A; 5002e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 5003e7931f94SStefano Zampini PetscMPIInt size,rank,color; 500452e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 500552e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 500627b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 500757de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 500827b6a85dSStefano Zampini PetscInt xadj_count, *count; 500927b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 501027b6a85dSStefano Zampini PetscSubcomm psubcomm; 501127b6a85dSStefano Zampini MPI_Comm subcomm; 501252e5ac9dSStefano Zampini PetscErrorCode ierr; 5013a57a6d2fSStefano Zampini 5014e7931f94SStefano Zampini PetscFunctionBegin; 501557de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 501657de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 501757de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 501857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 501957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 502057de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 502157de7509SStefano Zampini 502257de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 502357de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 502457de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 502557de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 502657de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 502757de7509SStefano Zampini im_active = !!(n); 502857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 502957de7509SStefano Zampini void_procs = size - active_procs; 503057de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 503157de7509SStefano Zampini if (void_procs) { 503257de7509SStefano Zampini PetscInt ncand; 503357de7509SStefano Zampini 503457de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 503557de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 503657de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 503757de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 503857de7509SStefano Zampini if (!procs_candidates[i]) { 503957de7509SStefano Zampini procs_candidates[ncand++] = i; 504057de7509SStefano Zampini } 504157de7509SStefano Zampini } 504257de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 504357de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 504457de7509SStefano Zampini } 504557de7509SStefano Zampini 504657de7509SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix */ 504757de7509SStefano Zampini if (active_procs < *n_subdomains) { 504857de7509SStefano Zampini PetscInt issize,isidx; 504957de7509SStefano Zampini if (im_active) { 505057de7509SStefano Zampini issize = 1; 505157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 505257de7509SStefano Zampini isidx = procs_candidates[rank]; 505357de7509SStefano Zampini } else { 505457de7509SStefano Zampini isidx = rank; 505557de7509SStefano Zampini } 505657de7509SStefano Zampini } else { 505757de7509SStefano Zampini issize = 0; 505857de7509SStefano Zampini isidx = -1; 505957de7509SStefano Zampini } 506057de7509SStefano Zampini *n_subdomains = active_procs; 506157de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 5062daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 506357de7509SStefano Zampini PetscFunctionReturn(0); 506457de7509SStefano Zampini } 5065c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 5066c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 506727b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 5068e7931f94SStefano Zampini 5069e7931f94SStefano Zampini /* Get info on mapping */ 50703bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 50713bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5072e7931f94SStefano Zampini 5073e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 5074785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 5075e7931f94SStefano Zampini xadj[0] = 0; 5076e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 5077785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 5078785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 507927b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 508027b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 508127b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 508227b6a85dSStefano Zampini count[shared[i][j]] += 1; 5083e7931f94SStefano Zampini 508427b6a85dSStefano Zampini xadj_count = 0; 50852b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 508627b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 508727b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 5088d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 5089d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 5090d023bfaeSStefano Zampini xadj_count++; 509127b6a85dSStefano Zampini break; 509227b6a85dSStefano Zampini } 5093e7931f94SStefano Zampini } 5094e7931f94SStefano Zampini } 5095d023bfaeSStefano Zampini xadj[1] = xadj_count; 509627b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 50973bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5098e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 5099e7931f94SStefano Zampini 51003837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 5101e7931f94SStefano Zampini 510227b6a85dSStefano Zampini /* Restrict work on active processes only */ 510327b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 510427b6a85dSStefano Zampini if (void_procs) { 510527b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 510627b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 510727b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 510827b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 510927b6a85dSStefano Zampini } else { 511027b6a85dSStefano Zampini psubcomm = NULL; 511127b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 511227b6a85dSStefano Zampini } 511327b6a85dSStefano Zampini 511427b6a85dSStefano Zampini v_wgt = NULL; 511527b6a85dSStefano Zampini if (!color) { 5116e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 5117e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 5118e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5119c8587f34SStefano Zampini } else { 512052e5ac9dSStefano Zampini Mat subdomain_adj; 512152e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 512252e5ac9dSStefano Zampini MatPartitioning partitioner; 512327b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 512452e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 512557de7509SStefano Zampini PetscMPIInt size; 5126b0c7d250SStefano Zampini PetscBool aggregate; 5127b0c7d250SStefano Zampini 512827b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 512927b6a85dSStefano Zampini if (void_procs) { 513027b6a85dSStefano Zampini PetscInt prank = rank; 5131785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 513227b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 5133e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 5134e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 5135c8587f34SStefano Zampini } 5136e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 513727b6a85dSStefano Zampini } else { 513827b6a85dSStefano Zampini oldranks = NULL; 513927b6a85dSStefano Zampini } 5140b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 514127b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 5142b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 5143b0c7d250SStefano Zampini PetscMPIInt nrank; 5144b0c7d250SStefano Zampini PetscScalar *vals; 5145b0c7d250SStefano Zampini 514627b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 5147b0c7d250SStefano Zampini lrows = 0; 5148b0c7d250SStefano Zampini if (nrank<redprocs) { 5149b0c7d250SStefano Zampini lrows = size/redprocs; 5150b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 5151b0c7d250SStefano Zampini } 515227b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 5153b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 5154b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5155b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5156b0c7d250SStefano Zampini row = nrank; 5157b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 5158b0c7d250SStefano Zampini cols = adjncy; 5159b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 5160b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 5161b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 5162b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5163b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 516452e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 516552e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 516652e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5167b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 516827b6a85dSStefano Zampini if (use_vwgt) { 516927b6a85dSStefano Zampini Vec v; 517027b6a85dSStefano Zampini const PetscScalar *array; 517127b6a85dSStefano Zampini PetscInt nl; 517227b6a85dSStefano Zampini 517327b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 517427b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 517527b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 517627b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 517727b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 517827b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 517927b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 518022db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 518127b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 518227b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 518327b6a85dSStefano Zampini } 5184b0c7d250SStefano Zampini } else { 518527b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 518627b6a85dSStefano Zampini if (use_vwgt) { 518727b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 518827b6a85dSStefano Zampini v_wgt[0] = local_size; 518927b6a85dSStefano Zampini } 5190b0c7d250SStefano Zampini } 519122b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 5192e7931f94SStefano Zampini 5193e7931f94SStefano Zampini /* Partition */ 519427b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 5195e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 519627b6a85dSStefano Zampini if (v_wgt) { 5197e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 5198c8587f34SStefano Zampini } 519957de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 520057de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 5201e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 5202e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 520322b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 5204e7931f94SStefano Zampini 520552e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 520652e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 520752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 520852e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 520957de7509SStefano Zampini if (!aggregate) { 521057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 521127b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 521227b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 521327b6a85dSStefano Zampini #endif 521457de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 521527b6a85dSStefano Zampini } else if (oldranks) { 5216b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 521727b6a85dSStefano Zampini } else { 521827b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 521957de7509SStefano Zampini } 522028143c3dSStefano Zampini } else { 5221b0c7d250SStefano Zampini PetscInt idxs[1]; 5222b0c7d250SStefano Zampini PetscMPIInt tag; 5223b0c7d250SStefano Zampini MPI_Request *reqs; 5224b0c7d250SStefano Zampini 5225b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 5226b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 5227b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 522827b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 522928143c3dSStefano Zampini } 523027b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 5231b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5232b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 523357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 523427b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 523527b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 523627b6a85dSStefano Zampini #endif 523757de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 523827b6a85dSStefano Zampini } else if (oldranks) { 5239b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 524027b6a85dSStefano Zampini } else { 524127b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 5242e7931f94SStefano Zampini } 524357de7509SStefano Zampini } 524452e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5245e7931f94SStefano Zampini /* clean up */ 5246e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 524752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 5248e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 5249e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 5250e7931f94SStefano Zampini } 525127b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 525257de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 5253e7931f94SStefano Zampini 5254e7931f94SStefano Zampini /* assemble parallel IS for sends */ 5255e7931f94SStefano Zampini i = 1; 525627b6a85dSStefano Zampini if (!color) i=0; 525757de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 5258e7931f94SStefano Zampini PetscFunctionReturn(0); 5259e7931f94SStefano Zampini } 5260e7931f94SStefano Zampini 5261e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 5262e7931f94SStefano Zampini 5263e7931f94SStefano Zampini #undef __FUNCT__ 5264e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 52651ae86dd6SStefano 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[]) 5266e7931f94SStefano Zampini { 526770cf5478SStefano Zampini Mat local_mat; 5268e7931f94SStefano Zampini IS is_sends_internal; 52699d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 52701ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 52719d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 5272e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 5273e7931f94SStefano Zampini PetscInt* l2gmap_indices; 5274e7931f94SStefano Zampini const PetscInt* is_indices; 5275e7931f94SStefano Zampini MatType new_local_type; 5276e7931f94SStefano Zampini /* buffers */ 5277e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 527828143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 52799d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 5280e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 52811ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 5282e7931f94SStefano Zampini /* MPI */ 528328143c3dSStefano Zampini MPI_Comm comm,comm_n; 528428143c3dSStefano Zampini PetscSubcomm subcomm; 5285e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 528628143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 528728143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 52881ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 52891ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 52901ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 5291e7931f94SStefano Zampini PetscErrorCode ierr; 5292e7931f94SStefano Zampini 5293e7931f94SStefano Zampini PetscFunctionBegin; 529457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5295e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 529628143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 529757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 529857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 529957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 530057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 530157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 53021ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 53031ae86dd6SStefano Zampini if (nvecs) { 53041ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 53051ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 53061ae86dd6SStefano Zampini } 530757de7509SStefano Zampini /* further checks */ 5308e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5309e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 5310e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 5311e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 5312e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 531357de7509SStefano Zampini if (reuse && *mat_n) { 531470cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 531557de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 531670cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 531728143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 531870cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 531970cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 532070cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 532170cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 532270cf5478SStefano Zampini } 5323e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 5324e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 532557de7509SStefano Zampini 5326e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 5327e7931f94SStefano Zampini if (!is_sends) { 532828143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 532957de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 5330c8587f34SStefano Zampini } else { 5331e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 5332e7931f94SStefano Zampini is_sends_internal = is_sends; 5333c8587f34SStefano Zampini } 5334e7931f94SStefano Zampini 5335e7931f94SStefano Zampini /* get comm */ 5336a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 5337e7931f94SStefano Zampini 5338e7931f94SStefano Zampini /* compute number of sends */ 5339e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 5340e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 5341e7931f94SStefano Zampini 5342e7931f94SStefano Zampini /* compute number of receives */ 5343e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 5344785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 5345e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 5346e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5347e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 5348e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 5349e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 5350e7931f94SStefano Zampini 535128143c3dSStefano Zampini /* restrict comm if requested */ 535228143c3dSStefano Zampini subcomm = 0; 535328143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 535428143c3dSStefano Zampini if (restrict_comm) { 5355779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 5356779c1cceSStefano Zampini 535728143c3dSStefano Zampini color = 0; 535853a05cb3SStefano Zampini if (restrict_full) { 535953a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 536053a05cb3SStefano Zampini } else { 536153a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 536253a05cb3SStefano Zampini } 5363b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 536428143c3dSStefano Zampini subcommsize = commsize - subcommsize; 536528143c3dSStefano Zampini /* check if reuse has been requested */ 536657de7509SStefano Zampini if (reuse) { 536728143c3dSStefano Zampini if (*mat_n) { 536828143c3dSStefano Zampini PetscMPIInt subcommsize2; 536928143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 537028143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 537128143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 537228143c3dSStefano Zampini } else { 537328143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 537428143c3dSStefano Zampini } 537528143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 5376779c1cceSStefano Zampini PetscMPIInt rank; 5377779c1cceSStefano Zampini 5378779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 537928143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 538028143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 538128143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 5382306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 538328143c3dSStefano Zampini } 538428143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 538528143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 538628143c3dSStefano Zampini } else { 538728143c3dSStefano Zampini comm_n = comm; 538828143c3dSStefano Zampini } 538928143c3dSStefano Zampini 5390e7931f94SStefano Zampini /* prepare send/receive buffers */ 5391785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 5392e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 5393785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 5394e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 539528143c3dSStefano Zampini if (nis) { 5396854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 539728143c3dSStefano Zampini } 5398e7931f94SStefano Zampini 539928143c3dSStefano Zampini /* Get data from local matrices */ 54006c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 5401e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 5402e7931f94SStefano Zampini /* 5403e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 5404e7931f94SStefano Zampini send_buffer_idxs should contain: 5405e7931f94SStefano Zampini - MatType_PRIVATE type 5406e7931f94SStefano Zampini - PetscInt size_of_l2gmap 5407e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 5408e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 5409e7931f94SStefano Zampini */ 54106c4ed002SBarry Smith else { 5411e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 54123bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 5413854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 5414e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 5415e7931f94SStefano Zampini send_buffer_idxs[1] = i; 54163bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5417e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 54183bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5419e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 5420e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5421e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 5422e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 5423c8587f34SStefano Zampini } 5424c8587f34SStefano Zampini } 5425e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 542628143c3dSStefano Zampini /* additional is (if any) */ 542728143c3dSStefano Zampini if (nis) { 542828143c3dSStefano Zampini PetscMPIInt psum; 542928143c3dSStefano Zampini PetscInt j; 543028143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 543128143c3dSStefano Zampini PetscInt plen; 543228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 543328143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 543428143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 543528143c3dSStefano Zampini } 5436854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 543728143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 543828143c3dSStefano Zampini PetscInt plen; 543928143c3dSStefano Zampini const PetscInt *is_array_idxs; 544028143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 544128143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 544228143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 544328143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 544428143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 544528143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 544628143c3dSStefano Zampini } 544728143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 544828143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 544928143c3dSStefano Zampini } 545028143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 545128143c3dSStefano Zampini } 545228143c3dSStefano Zampini 5453e7931f94SStefano Zampini buf_size_idxs = 0; 5454e7931f94SStefano Zampini buf_size_vals = 0; 545528143c3dSStefano Zampini buf_size_idxs_is = 0; 54561ae86dd6SStefano Zampini buf_size_vecs = 0; 5457e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5458e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 5459e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 546028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 54611ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 5462e7931f94SStefano Zampini } 5463785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 5464785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 546595ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 54661ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 5467e7931f94SStefano Zampini 5468e7931f94SStefano Zampini /* get new tags for clean communications */ 5469e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 5470e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 547128143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 54721ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 5473e7931f94SStefano Zampini 5474e7931f94SStefano Zampini /* allocate for requests */ 5475785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 5476785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 547795ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 54781ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 5479785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 5480785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 548195ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 54821ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 5483e7931f94SStefano Zampini 5484e7931f94SStefano Zampini /* communications */ 5485e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5486e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 548728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 54881ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 5489e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5490e7931f94SStefano Zampini source_dest = onodes[i]; 5491e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 5492e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 5493e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5494e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 549528143c3dSStefano Zampini if (nis) { 549657de7509SStefano Zampini source_dest = onodes_is[i]; 549728143c3dSStefano 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); 549828143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 549928143c3dSStefano Zampini } 55001ae86dd6SStefano Zampini if (nvecs) { 55011ae86dd6SStefano Zampini source_dest = onodes[i]; 55021ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 55031ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 55041ae86dd6SStefano Zampini } 5505e7931f94SStefano Zampini } 5506e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5507e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 5508e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 5509e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 551028143c3dSStefano Zampini if (nis) { 551128143c3dSStefano 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); 551228143c3dSStefano Zampini } 55131ae86dd6SStefano Zampini if (nvecs) { 55141ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 55151ae86dd6SStefano 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); 55161ae86dd6SStefano Zampini } 5517e7931f94SStefano Zampini } 5518e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5519e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 5520e7931f94SStefano Zampini 5521e7931f94SStefano Zampini /* assemble new l2g map */ 5522e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5523e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 55249d30be91SStefano Zampini new_local_rows = 0; 5525e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 55269d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5527e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5528e7931f94SStefano Zampini } 55299d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 5530e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 55319d30be91SStefano Zampini new_local_rows = 0; 5532e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 55339d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 55349d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5535e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5536e7931f94SStefano Zampini } 55379d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 55389d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 5539e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 5540e7931f94SStefano Zampini 5541e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 5542e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 5543e7931f94SStefano 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) */ 5544e7931f94SStefano Zampini if (n_recvs) { 554528143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 5546e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5547e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5548e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 5549e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 5550e7931f94SStefano Zampini break; 5551e7931f94SStefano Zampini } 5552e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5553e7931f94SStefano Zampini } 5554e7931f94SStefano Zampini switch (new_local_type_private) { 555528143c3dSStefano Zampini case MATDENSE_PRIVATE: 555628143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 5557e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5558e7931f94SStefano Zampini bs = 1; 555928143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 556028143c3dSStefano Zampini new_local_type = MATSEQDENSE; 556128143c3dSStefano Zampini bs = 1; 556228143c3dSStefano Zampini } 5563e7931f94SStefano Zampini break; 5564e7931f94SStefano Zampini case MATAIJ_PRIVATE: 5565e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5566e7931f94SStefano Zampini bs = 1; 5567e7931f94SStefano Zampini break; 5568e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 5569e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 5570e7931f94SStefano Zampini break; 5571e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 5572e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 5573e7931f94SStefano Zampini break; 5574e7931f94SStefano Zampini default: 55759d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 5576e7931f94SStefano Zampini break; 5577e7931f94SStefano Zampini } 557828143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 557928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 558028143c3dSStefano Zampini bs = 1; 5581e7931f94SStefano Zampini } 5582e7931f94SStefano Zampini 558370cf5478SStefano Zampini /* create MATIS object if needed */ 558457de7509SStefano Zampini if (!reuse) { 5585e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 5586e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 558770cf5478SStefano Zampini } else { 558870cf5478SStefano Zampini /* it also destroys the local matrices */ 558957de7509SStefano Zampini if (*mat_n) { 559070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 559157de7509SStefano Zampini } else { /* this is a fake object */ 559257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 559357de7509SStefano Zampini } 559470cf5478SStefano Zampini } 559570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 5596e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 55979d30be91SStefano Zampini 55989d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 55999d30be91SStefano Zampini 56009d30be91SStefano Zampini /* Global to local map of received indices */ 56019d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 56029d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 56039d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 56049d30be91SStefano Zampini 56059d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 56069d30be91SStefano Zampini buf_size_idxs = 0; 56079d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 56089d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 56099d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 56109d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 56119d30be91SStefano Zampini } 56129d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 56139d30be91SStefano Zampini 56149d30be91SStefano Zampini /* set preallocation */ 56159d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 56169d30be91SStefano Zampini if (!newisdense) { 56179d30be91SStefano Zampini PetscInt *new_local_nnz=0; 56189d30be91SStefano Zampini 56199d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 56209d30be91SStefano Zampini if (n_recvs) { 56219d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 56229d30be91SStefano Zampini } 56239d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 56249d30be91SStefano Zampini PetscInt j; 56259d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 56269d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 56279d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 56289d30be91SStefano Zampini } 56299d30be91SStefano Zampini } else { 56309d30be91SStefano Zampini /* TODO */ 56319d30be91SStefano Zampini } 56329d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 56339d30be91SStefano Zampini } 56349d30be91SStefano Zampini if (new_local_nnz) { 56359d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 56369d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 56379d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 56389d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 56399d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 56409d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 56419d30be91SStefano Zampini } else { 56429d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 56439d30be91SStefano Zampini } 56449d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 56459d30be91SStefano Zampini } else { 56469d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 56479d30be91SStefano Zampini } 5648e7931f94SStefano Zampini 5649e7931f94SStefano Zampini /* set values */ 5650e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 56519d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5652e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5653e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5654e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 56559d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5656e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5657e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5658e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 565928143c3dSStefano Zampini } else { 566028143c3dSStefano Zampini /* TODO */ 5661e7931f94SStefano Zampini } 5662e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5663e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5664e7931f94SStefano Zampini } 5665e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5666e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 566770cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 566870cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 56699d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 5670e7931f94SStefano Zampini 5671dfd14d43SStefano Zampini #if 0 567228143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5673e7931f94SStefano Zampini Vec lvec,rvec; 5674e7931f94SStefano Zampini PetscReal infty_error; 5675e7931f94SStefano Zampini 56762a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5677e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5678e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5679e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 568070cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5681e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5682e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5683e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5684e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5685e7931f94SStefano Zampini } 568628143c3dSStefano Zampini #endif 5687e7931f94SStefano Zampini 568828143c3dSStefano Zampini /* assemble new additional is (if any) */ 568928143c3dSStefano Zampini if (nis) { 569028143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 569128143c3dSStefano Zampini 569228143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5693854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 569428143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 569528143c3dSStefano Zampini psum = 0; 569628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 569728143c3dSStefano Zampini for (j=0;j<nis;j++) { 569828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 569928143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 570028143c3dSStefano Zampini psum += plen; 570128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 570228143c3dSStefano Zampini } 570328143c3dSStefano Zampini } 5704854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5705854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 570628143c3dSStefano Zampini for (i=1;i<nis;i++) { 570728143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 570828143c3dSStefano Zampini } 570928143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 571028143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 571128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 571228143c3dSStefano Zampini for (j=0;j<nis;j++) { 571328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 571428143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 571528143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 571628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 571728143c3dSStefano Zampini } 571828143c3dSStefano Zampini } 571928143c3dSStefano Zampini for (i=0;i<nis;i++) { 572028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 572128143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 572228143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 572328143c3dSStefano Zampini } 572428143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 572528143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 572628143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 572728143c3dSStefano Zampini } 5728e7931f94SStefano Zampini /* free workspace */ 572928143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5730e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5731e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5732e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5733e7931f94SStefano Zampini if (isdense) { 5734e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5735e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5736e7931f94SStefano Zampini } else { 5737e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5738e7931f94SStefano Zampini } 573928143c3dSStefano Zampini if (nis) { 574028143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 574128143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 574228143c3dSStefano Zampini } 57431ae86dd6SStefano Zampini 57441ae86dd6SStefano Zampini if (nvecs) { 57451ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 57461ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 57471ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 57481ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 57491ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 57501ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 57511ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 57521ae86dd6SStefano Zampini /* set values */ 57531ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 57541ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 57551ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 57561ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 57571ae86dd6SStefano Zampini PetscInt j; 57581ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 57591ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 57601ae86dd6SStefano Zampini } 57611ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 57621ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 57631ae86dd6SStefano Zampini } 57641ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 57651ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 57661ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 57671ae86dd6SStefano Zampini } 57681ae86dd6SStefano Zampini 57691ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 57701ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5771e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5772e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 57731ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 577428143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5775e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5776e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 57771ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 577828143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5779e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5780e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5781e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5782e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5783e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 578428143c3dSStefano Zampini if (nis) { 578528143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 578628143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 578728143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 578828143c3dSStefano Zampini } 578928143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 579028143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 579128143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 579228143c3dSStefano Zampini for (i=0;i<nis;i++) { 579328143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 579428143c3dSStefano Zampini } 57951ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 57961ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 57971ae86dd6SStefano Zampini } 579853a05cb3SStefano Zampini *mat_n = NULL; 579928143c3dSStefano Zampini } 5800e7931f94SStefano Zampini PetscFunctionReturn(0); 5801e7931f94SStefano Zampini } 5802a57a6d2fSStefano Zampini 580312edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5804af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 580512edc857SStefano Zampini 5806c8587f34SStefano Zampini #undef __FUNCT__ 5807c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5808c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5809c8587f34SStefano Zampini { 5810c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5811c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 581220a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 58131ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 58149881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 581520a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 58166e683305SStefano Zampini IS coarse_is,*isarray; 58176e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 581830368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5819f9eb5b7dSStefano Zampini PC pc_temp; 5820c8587f34SStefano Zampini PCType coarse_pc_type; 5821c8587f34SStefano Zampini KSPType coarse_ksp_type; 5822f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 58234f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 58246e683305SStefano Zampini Mat t_coarse_mat_is; 582557de7509SStefano Zampini PetscInt ncoarse; 582668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 582722bc73bbSStefano Zampini PetscScalar *array; 582857de7509SStefano Zampini MatReuse coarse_mat_reuse; 582957de7509SStefano Zampini PetscBool restr, full_restr, have_void; 58309881197aSStefano Zampini PetscErrorCode ierr; 5831fdc09c96SStefano Zampini 5832c8587f34SStefano Zampini PetscFunctionBegin; 5833c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 583468457ee5SStefano 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 */ 5835fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 58365a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5837fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5838f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5839f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5840f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5841fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 584251bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 584351bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5844dc4bcba2SStefano Zampini PC pc; 5845dc4bcba2SStefano Zampini PetscBool isbddc; 5846dc4bcba2SStefano Zampini 5847dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5848dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5849dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5850dc4bcba2SStefano Zampini if (isbddc) { 585163c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 585263c961adSStefano Zampini } else { 5853727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 585463c961adSStefano Zampini } 5855fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5856fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5857fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5858f4ddd8eeSStefano Zampini } 5859fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5860fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5861f4ddd8eeSStefano Zampini } 586270cf5478SStefano Zampini /* reset any subassembling information */ 586357de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 586470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 586557de7509SStefano Zampini } 58666e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5867fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5868f4ddd8eeSStefano Zampini } 586957de7509SStefano Zampini /* assemble coarse matrix */ 587057de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 587157de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 587257de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 587357de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 587418a45a71SStefano Zampini } else { 587557de7509SStefano Zampini coarse_mat = NULL; 587657de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 58776e683305SStefano Zampini } 5878e7931f94SStefano Zampini 5879abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5880abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5881abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5882abbbba34SStefano Zampini 5883abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 588422bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 588522bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 588622bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 588722bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5888e176bc59SStefano 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); 58896e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 58906e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 58916e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5892abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5893abbbba34SStefano Zampini 589457de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 589557de7509SStefano Zampini im_active = !!(pcis->n); 589657de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 589757de7509SStefano Zampini 589857de7509SStefano Zampini /* determine number of process partecipating to coarse solver and compute subassembling pattern */ 589957de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 590057de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 590157de7509SStefano Zampini coarse_mat_is = NULL; 590257de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 590357de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 590457de7509SStefano Zampini full_restr = PETSC_TRUE; 59051ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 590657de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 590757de7509SStefano Zampini if (multilevel_requested) { 590857de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 590957de7509SStefano Zampini restr = PETSC_FALSE; 591057de7509SStefano Zampini full_restr = PETSC_FALSE; 591157de7509SStefano Zampini } else { 591257de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 591357de7509SStefano Zampini restr = PETSC_TRUE; 591457de7509SStefano Zampini full_restr = PETSC_TRUE; 591557de7509SStefano Zampini } 59164b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 591757de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 591857de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 5919*a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 592057de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 5921*a198735bSStefano Zampini } else { 5922*a198735bSStefano Zampini PetscMPIInt size,rank; 5923*a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 5924*a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 5925*a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 5926*a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 5927*a198735bSStefano Zampini } 592857de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 592957de7509SStefano Zampini PetscInt psum; 593057de7509SStefano Zampini PetscMPIInt size; 593157de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 593257de7509SStefano Zampini else psum = 0; 593357de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 593457de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 593557de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 593657de7509SStefano Zampini } 593757de7509SStefano Zampini /* determine if we can go multilevel */ 593857de7509SStefano Zampini if (multilevel_requested) { 593957de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 594057de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 594157de7509SStefano Zampini } 594257de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 594357de7509SStefano Zampini 5944e4d548c7SStefano Zampini /* dump subassembling pattern */ 5945e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 5946e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 5947e4d548c7SStefano Zampini } 5948e4d548c7SStefano Zampini 59496e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 595027b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 59516e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 59526e683305SStefano Zampini const PetscInt *idxs; 59536e683305SStefano Zampini ISLocalToGlobalMapping tmap; 59546e683305SStefano Zampini 59556e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 59560be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 59576e683305SStefano Zampini /* allocate space for temporary storage */ 5958854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5959854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 59606e683305SStefano Zampini /* allocate for IS array */ 59616e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 59626e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 596327b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 596430368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5965854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 59666e683305SStefano Zampini /* dofs splitting */ 59676e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 59686e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 59696e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 59706e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 59716e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 59726e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 59736e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 597430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 59756e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 59766e683305SStefano Zampini } 59776e683305SStefano Zampini /* neumann boundaries */ 59786e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 59796e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 59806e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 59816e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 59826e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 59836e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 59846e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 598530368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 59866e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 59876e683305SStefano Zampini } 59886e683305SStefano Zampini /* free memory */ 59896e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 59906e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 59916e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 59926e683305SStefano Zampini } else { 59936e683305SStefano Zampini nis = 0; 59946e683305SStefano Zampini nisdofs = 0; 59956e683305SStefano Zampini nisneu = 0; 599630368db7SStefano Zampini nisvert = 0; 59976e683305SStefano Zampini isarray = NULL; 59986e683305SStefano Zampini } 59996e683305SStefano Zampini /* destroy no longer needed map */ 60006e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 60016e683305SStefano Zampini 600257de7509SStefano Zampini /* subassemble */ 600357de7509SStefano Zampini if (multilevel_allowed) { 60041ae86dd6SStefano Zampini Vec vp[1]; 60051ae86dd6SStefano Zampini PetscInt nvecs = 0; 600657de7509SStefano Zampini PetscBool reuse,reuser; 60071ae86dd6SStefano Zampini 600857de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 600957de7509SStefano Zampini else reuse = PETSC_FALSE; 601057de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 60111ae86dd6SStefano Zampini vp[0] = NULL; 60121ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 60131ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 60141ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 60151ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 60161ae86dd6SStefano Zampini nvecs = 1; 60171ae86dd6SStefano Zampini 60181ae86dd6SStefano Zampini if (pcbddc->divudotp) { 6019*a198735bSStefano Zampini Mat B,loc_divudotp; 60201ae86dd6SStefano Zampini Vec v,p; 60211ae86dd6SStefano Zampini IS dummy; 60221ae86dd6SStefano Zampini PetscInt np; 60231ae86dd6SStefano Zampini 6024*a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 6025*a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 60261ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 6027*a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 60281ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 60291ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 60301ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 60311ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 60321ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 60331ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 60341ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 60351ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 60361ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 60371ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 60381ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 60391ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 604074e2c79eSStefano Zampini } 60411ae86dd6SStefano Zampini } 60421ae86dd6SStefano Zampini if (reuser) { 60431ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 604474e2c79eSStefano Zampini } else { 60451ae86dd6SStefano 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); 60461ae86dd6SStefano Zampini } 60471ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 60481ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 60491ae86dd6SStefano Zampini PetscInt nl; 60501ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 60511ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 60521ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 60531ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 60541ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 60551ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 60561ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 60571ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 6058*a198735bSStefano Zampini } else { 6059*a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 60601ae86dd6SStefano Zampini } 60611ae86dd6SStefano Zampini } else { 60621ae86dd6SStefano 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); 60636e683305SStefano Zampini } 606457de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 606557de7509SStefano Zampini PetscMPIInt size; 606657de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 606757de7509SStefano Zampini if (!multilevel_allowed) { 606857de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 60696e683305SStefano Zampini } else { 607057de7509SStefano Zampini Mat A; 6071779c1cceSStefano Zampini 607257de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 607357de7509SStefano Zampini if (coarse_mat_is) { 607457de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 607557de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 607657de7509SStefano Zampini coarse_mat = coarse_mat_is; 607757de7509SStefano Zampini } 607857de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 607957de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 608057de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 6081779c1cceSStefano Zampini } 6082779c1cceSStefano Zampini } 608357de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 608457de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 60856e683305SStefano Zampini 60866e683305SStefano Zampini /* create local to global scatters for coarse problem */ 608768457ee5SStefano Zampini if (compute_vecs) { 60886e683305SStefano Zampini PetscInt lrows; 60896e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 609057de7509SStefano Zampini if (coarse_mat) { 609157de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 60926e683305SStefano Zampini } else { 60936e683305SStefano Zampini lrows = 0; 60946e683305SStefano Zampini } 60956e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 60966e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 60976e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 60986e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 60996e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 61006e683305SStefano Zampini } 61016e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 6102c8587f34SStefano Zampini 6103f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 6104f9eb5b7dSStefano Zampini if (multilevel_allowed) { 6105f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 6106f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 6107f9eb5b7dSStefano Zampini } else { 6108f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 6109f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 6110c8587f34SStefano Zampini } 6111c8587f34SStefano Zampini 61126e683305SStefano Zampini /* print some info if requested */ 61136e683305SStefano Zampini if (pcbddc->dbg_flag) { 61146e683305SStefano Zampini if (!multilevel_allowed) { 61156e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 61166e683305SStefano Zampini if (multilevel_requested) { 61176e683305SStefano 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); 61186e683305SStefano Zampini } else if (pcbddc->max_levels) { 61196e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 61206e683305SStefano Zampini } 61216e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 61226e683305SStefano Zampini } 61236e683305SStefano Zampini } 61246e683305SStefano Zampini 6125f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 612657de7509SStefano Zampini if (coarse_mat) { 61276a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 61286e683305SStefano Zampini if (pcbddc->dbg_flag) { 612957de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 61306e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 61316e683305SStefano Zampini } 6132f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 6133312be037SStefano Zampini char prefix[256],str_level[16]; 6134e604994aSStefano Zampini size_t len; 613557de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 6136422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 6137c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 6138f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 613957de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6140c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 61416e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 6142c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 6143c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6144e604994aSStefano Zampini /* prefix */ 6145e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 6146e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 6147e604994aSStefano Zampini if (!pcbddc->current_level) { 6148e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 6149e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 6150c8587f34SStefano Zampini } else { 6151e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 6152312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 6153312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 615434d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 6155312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 6156e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 6157e604994aSStefano Zampini } 6158e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 61593e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 61603e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 61613e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 61623e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 6163f9eb5b7dSStefano Zampini /* allow user customization */ 6164f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 61653e3c6dadSStefano Zampini } 61663e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 616751bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 61683e3c6dadSStefano Zampini if (nisdofs) { 61693e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 61703e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 61713e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 61723e3c6dadSStefano Zampini } 61733e3c6dadSStefano Zampini } 61743e3c6dadSStefano Zampini if (nisneu) { 61753e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 61763e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 6177312be037SStefano Zampini } 617830368db7SStefano Zampini if (nisvert) { 617930368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 618030368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 618130368db7SStefano Zampini } 6182f9eb5b7dSStefano Zampini 6183f9eb5b7dSStefano Zampini /* get some info after set from options */ 6184f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 6185f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 61864f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 61876e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 6188f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6189f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 6190f9eb5b7dSStefano Zampini } 619139f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 61924f3a063dSStefano Zampini if (isredundant) { 61934f3a063dSStefano Zampini KSP inner_ksp; 61944f3a063dSStefano Zampini PC inner_pc; 61954f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 61964f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 61974f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 61984f3a063dSStefano Zampini } 6199f9eb5b7dSStefano Zampini 620057de7509SStefano Zampini /* parameters which miss an API */ 620157de7509SStefano Zampini if (isbddc) { 6202720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 6203720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 620457de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 620527b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 620627b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 6207*a198735bSStefano Zampini Mat coarsedivudotp_is; 6208*a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 6209*a198735bSStefano Zampini IS row,col; 6210*a198735bSStefano Zampini const PetscInt *gidxs; 6211*a198735bSStefano Zampini PetscInt n,st,M,N; 6212*a198735bSStefano Zampini 6213*a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 6214*a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 6215*a198735bSStefano Zampini st = st-n; 6216*a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 6217*a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 6218*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 6219*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6220*a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 6221*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6222*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 6223*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 6224*a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 6225*a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 6226*a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 6227*a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 6228*a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 6229*a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 6230*a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 6231*a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 6232*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6233*a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6234*a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 6235*a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 6236*a198735bSStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,NULL);CHKERRQ(ierr); 6237*a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 6238720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 623959e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 6240720d30f9SStefano Zampini } 6241d4d8cf7bSStefano Zampini } 62429881197aSStefano Zampini 62433301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 62445a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 62453301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 62463301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 62473301b35fSStefano Zampini } 62483301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 62493301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 62503301b35fSStefano Zampini } 62513301b35fSStefano Zampini if (pc->pmat->spd_set) { 62523301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 62533301b35fSStefano Zampini } 625427b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 625527b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 625627b6a85dSStefano Zampini } 62576e683305SStefano Zampini /* set operators */ 62585f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 62596e683305SStefano Zampini if (pcbddc->dbg_flag) { 62606e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 62616e683305SStefano Zampini } 62626e683305SStefano Zampini } 62636e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 6264b1ecc7b1SStefano Zampini #if 0 6265b9b85e73SStefano Zampini { 6266b9b85e73SStefano Zampini PetscViewer viewer; 6267b9b85e73SStefano Zampini char filename[256]; 6268b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 6269b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 62706a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6271b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 6272f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 6273b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 6274b9b85e73SStefano Zampini } 6275b9b85e73SStefano Zampini #endif 6276f9eb5b7dSStefano Zampini 627798a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 627898a51de6SStefano Zampini Vec crhs,csol; 627904708bb6SStefano Zampini 6280f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 6281f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 6282f347579bSStefano Zampini if (!csol) { 62832a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 6284f9eb5b7dSStefano Zampini } 6285f347579bSStefano Zampini if (!crhs) { 62862a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 6287f347579bSStefano Zampini } 6288b0f5fe93SStefano Zampini } 62891ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 6290b0f5fe93SStefano Zampini 6291b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 6292b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 6293b0f5fe93SStefano Zampini 6294b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 62954f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 62964f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 62974f1b2e48SStefano Zampini } 6298b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 6299b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 6300b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6301b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6302b0f5fe93SStefano Zampini if (coarse_mat) { 6303b0f5fe93SStefano Zampini Vec nullv; 6304b0f5fe93SStefano Zampini PetscScalar *array,*array2; 6305b0f5fe93SStefano Zampini PetscInt nl; 6306b0f5fe93SStefano Zampini 6307b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 6308b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 6309b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6310b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 6311b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 6312b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 6313b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6314b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 6315b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 6316b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 6317b0f5fe93SStefano Zampini } 6318b0f5fe93SStefano Zampini } 6319b0f5fe93SStefano Zampini 6320b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 6321b0f5fe93SStefano Zampini PetscBool ispreonly; 6322b0f5fe93SStefano Zampini 6323b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6324b0f5fe93SStefano Zampini PetscBool isnull; 6325b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 6326bef83e63SStefano Zampini if (isnull) { 6327b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 6328b0f5fe93SStefano Zampini } 6329bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 6330b0f5fe93SStefano Zampini } 6331b0f5fe93SStefano Zampini /* setup coarse ksp */ 6332b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 6333cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 6334cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 63356e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 6336c8587f34SStefano Zampini KSP check_ksp; 63372b510759SStefano Zampini KSPType check_ksp_type; 6338c8587f34SStefano Zampini PC check_pc; 63396e683305SStefano Zampini Vec check_vec,coarse_vec; 63406a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 63412b510759SStefano Zampini PetscInt its; 63426e683305SStefano Zampini PetscBool compute_eigs; 63436e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 63446e683305SStefano Zampini PetscInt neigs; 63458e185a42SStefano Zampini const char *prefix; 6346c8587f34SStefano Zampini 63472b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 63486e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 6349422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 635023ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6351f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 6352e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 6353e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 6354e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 63552b510759SStefano Zampini if (ispreonly) { 63562b510759SStefano Zampini check_ksp_type = KSPPREONLY; 63576e683305SStefano Zampini compute_eigs = PETSC_FALSE; 63582b510759SStefano Zampini } else { 6359cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 63606e683305SStefano Zampini compute_eigs = PETSC_TRUE; 6361c8587f34SStefano Zampini } 6362c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 63636e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 63646e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 63656e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 6366a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 6367a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 6368a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 6369a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 6370c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 6371c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 6372c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 6373c8587f34SStefano Zampini /* create random vec */ 63742701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 6375c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 63766e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 6377c8587f34SStefano Zampini /* solve coarse problem */ 63786e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 6379cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 63806e683305SStefano Zampini if (compute_eigs) { 6381854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 6382854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 63836e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 63841ae86dd6SStefano Zampini if (neigs) { 63856e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 63866e683305SStefano Zampini lambda_min = eigs_r[0]; 63876e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 63882701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 63892701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 6390cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 6391cbcc2c2aSStefano Zampini } 6392c8587f34SStefano Zampini } 6393c8587f34SStefano Zampini } 63941ae86dd6SStefano Zampini } 6395cbcc2c2aSStefano Zampini 6396c8587f34SStefano Zampini /* check coarse problem residual error */ 63976e683305SStefano Zampini if (pcbddc->dbg_flag) { 63986e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 63996e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 64006e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 6401c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 64026e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 64036e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 6404779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 64056e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 64066e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 64076e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 64086e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 6409b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6410b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 6411b0f5fe93SStefano Zampini } 64126e683305SStefano Zampini if (compute_eigs) { 64136e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 6414deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 6415c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 64166e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 64176e683305SStefano 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); 64186e683305SStefano Zampini for (i=0;i<neigs;i++) { 64196e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 6420c8587f34SStefano Zampini } 64216e683305SStefano Zampini } 64226e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 64236e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 64246e683305SStefano Zampini } 6425e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 64262701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 6427c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 64286e683305SStefano Zampini if (compute_eigs) { 64296e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 64306e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 6431c8587f34SStefano Zampini } 64326e683305SStefano Zampini } 64336e683305SStefano Zampini } 6434bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 6435cbcc2c2aSStefano Zampini /* print additional info */ 6436cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 64376e683305SStefano Zampini /* waits until all processes reaches this point */ 64386e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 6439cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 6440cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6441cbcc2c2aSStefano Zampini } 6442cbcc2c2aSStefano Zampini 64432b510759SStefano Zampini /* free memory */ 6444fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 6445c8587f34SStefano Zampini PetscFunctionReturn(0); 6446c8587f34SStefano Zampini } 6447674ae819SStefano Zampini 6448f34684f1SStefano Zampini #undef __FUNCT__ 6449f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 6450f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 6451f34684f1SStefano Zampini { 6452f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6453f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 6454f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 6455dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 6456dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 645773be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 6458dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 6459f34684f1SStefano Zampini PetscErrorCode ierr; 6460f34684f1SStefano Zampini 6461f34684f1SStefano Zampini PetscFunctionBegin; 6462f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 64636c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 6464dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 64653bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 6466dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6467dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 6468dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 6469dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 6470dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 6471dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 64726c4ed002SBarry 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); 6473dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 6474dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6475dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 6476dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6477dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6478f34684f1SStefano Zampini 6479f34684f1SStefano Zampini /* check numbering */ 6480f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 6481019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 6482dc456d91SStefano Zampini PetscInt i; 6483b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 6484f34684f1SStefano Zampini 6485f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6486f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 6487f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 64881575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6489019a44ceSStefano Zampini /* counter */ 6490019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6491019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6492019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6493019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6494019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6495019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6496f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 6497f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 6498727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6499f34684f1SStefano Zampini } 6500f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6501f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6502f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6503e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6504e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6505e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6506e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6507f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6508019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6509f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6510019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 65112c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 651275c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 6513b9b85e73SStefano Zampini set_error = PETSC_TRUE; 65142c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 65152c66d082SStefano 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); 6516f34684f1SStefano Zampini } 6517f34684f1SStefano Zampini } 6518019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6519b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 6520f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6521f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6522f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 6523f34684f1SStefano Zampini } 6524f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6525f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6526e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6527e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6528f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 6529f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 6530b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 6531ca8b9ea9SStefano Zampini PetscInt *gidxs; 6532ca8b9ea9SStefano Zampini 6533ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 65343bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 6535f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 6536f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6537f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6538f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 65394bc2dc4bSStefano 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); 6540f34684f1SStefano Zampini } 6541f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6542ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 6543f34684f1SStefano Zampini } 6544f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 65451575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6546302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 6547f34684f1SStefano Zampini } 65488bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 6549f34684f1SStefano Zampini /* get back data */ 6550f34684f1SStefano Zampini *coarse_size_n = coarse_size; 6551f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 6552674ae819SStefano Zampini PetscFunctionReturn(0); 6553674ae819SStefano Zampini } 6554674ae819SStefano Zampini 6555e456f2a8SStefano Zampini #undef __FUNCT__ 6556e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 6557a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 6558e456f2a8SStefano Zampini { 6559e456f2a8SStefano Zampini IS localis_t; 6560a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 6561e456f2a8SStefano Zampini PetscScalar *vals; 6562e456f2a8SStefano Zampini PetscErrorCode ierr; 6563e456f2a8SStefano Zampini 6564e456f2a8SStefano Zampini PetscFunctionBegin; 6565a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 6566e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 6567854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 6568e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 6569e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6570a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 6571a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 65721035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 6573a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 65741035eff8SStefano Zampini } 6575a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 6576e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6577e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6578a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 6579a7dc3881SStefano Zampini /* now compute set in local ordering */ 6580a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6581a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6582a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6583a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 6584a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6585ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6586e456f2a8SStefano Zampini lsize++; 6587e456f2a8SStefano Zampini } 6588e456f2a8SStefano Zampini } 6589854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 6590a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6591ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6592e456f2a8SStefano Zampini idxs[lsize++] = i; 6593e456f2a8SStefano Zampini } 6594e456f2a8SStefano Zampini } 6595a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6596a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 6597e456f2a8SStefano Zampini *localis = localis_t; 6598e456f2a8SStefano Zampini PetscFunctionReturn(0); 6599e456f2a8SStefano Zampini } 6600906d46d4SStefano Zampini 6601b96c3477SStefano Zampini #undef __FUNCT__ 6602b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 660308122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 6604b96c3477SStefano Zampini { 6605a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6606b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6607b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6608a64f4aa4SStefano Zampini Mat S_j; 6609b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6610b96c3477SStefano Zampini PetscBool free_used_adj; 6611b96c3477SStefano Zampini PetscErrorCode ierr; 6612b96c3477SStefano Zampini 6613b96c3477SStefano Zampini PetscFunctionBegin; 6614b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6615b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 661608122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6617b96c3477SStefano Zampini used_xadj = NULL; 6618b96c3477SStefano Zampini used_adjncy = NULL; 6619b96c3477SStefano Zampini } else { 662008122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 662108122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 662208122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 662308122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6624b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6625b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6626b96c3477SStefano Zampini } else { 66272fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6628b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6629b96c3477SStefano Zampini PetscInt nvtxs; 6630b96c3477SStefano Zampini 66312fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 66322fffb893SStefano Zampini if (flg_row) { 6633b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6634b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6635b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6636b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 66372fffb893SStefano Zampini } else { 66382fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 66392fffb893SStefano Zampini used_xadj = NULL; 66402fffb893SStefano Zampini used_adjncy = NULL; 66412fffb893SStefano Zampini } 66422fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6643b96c3477SStefano Zampini } 6644b96c3477SStefano Zampini } 6645d5574798SStefano Zampini 6646d5574798SStefano Zampini /* setup sub_schurs data */ 6647a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6648df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 6649df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 6650a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 665191af6908SStefano 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); 6652a64f4aa4SStefano Zampini } else { 66536816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 6654b7ab4a40SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE;; 6655a3df083aSStefano Zampini PetscInt benign_n; 665672b8c272SStefano Zampini Mat change = NULL; 66579d54b7f4SStefano Zampini Vec scaling = NULL; 665872b8c272SStefano Zampini IS change_primal = NULL; 6659a3df083aSStefano Zampini 66605feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 66615feab87aSStefano Zampini PetscInt n_vertices; 66625feab87aSStefano Zampini 66635feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 66642034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 66655feab87aSStefano Zampini } 666604708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 666704708bb6SStefano Zampini if (!isseqaij) { 666804708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 666904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 667004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 667104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 667204708bb6SStefano Zampini } else { 6673511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 667404708bb6SStefano Zampini } 667504708bb6SStefano Zampini } 6676a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6677a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6678ca92afb2SStefano Zampini } else { 6679a3df083aSStefano Zampini benign_n = 0; 6680ca92afb2SStefano Zampini } 6681b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 6682b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 6683b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 668472b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 668522db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 6686b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 668722db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 6688b7ab4a40SStefano Zampini } 6689b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 6690b7ab4a40SStefano 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 */ 6691b7ab4a40SStefano Zampini if (need_change) { 669288c03ad3SStefano Zampini PC_IS *pcisf; 669388c03ad3SStefano Zampini PC_BDDC *pcbddcf; 669488c03ad3SStefano Zampini PC pcf; 669588c03ad3SStefano Zampini 6696e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 669788c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 669888c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 669988c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 670088c03ad3SStefano Zampini /* hacks */ 670188c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 670272b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 670372b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 670472b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 670572b8c272SStefano Zampini pcisf->n = pcis->n; 670672b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 670788c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 670888c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 670988c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 671088c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 671188c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 671288c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 671372b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 671488c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 671588c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 671672b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 671772b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 671872b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 671972b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 672072b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 672188c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 672272b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 672388c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 672488c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 672588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 672688c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 672788c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 672888c03ad3SStefano Zampini pcf->ops->destroy = NULL; 672988c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 673088c03ad3SStefano Zampini } 67319d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 673291af6908SStefano 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); 673372b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 673472b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 6735ca92afb2SStefano Zampini } 6736d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6737b96c3477SStefano Zampini 6738b96c3477SStefano Zampini /* free adjacency */ 6739b96c3477SStefano Zampini if (free_used_adj) { 6740b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6741b96c3477SStefano Zampini } 6742b96c3477SStefano Zampini PetscFunctionReturn(0); 6743b96c3477SStefano Zampini } 6744b96c3477SStefano Zampini 6745b96c3477SStefano Zampini #undef __FUNCT__ 6746b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 674708122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6748b96c3477SStefano Zampini { 6749b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6750b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6751b96c3477SStefano Zampini PCBDDCGraph graph; 6752b96c3477SStefano Zampini PetscErrorCode ierr; 6753b96c3477SStefano Zampini 6754b96c3477SStefano Zampini PetscFunctionBegin; 6755b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 675608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 67573301b35fSStefano Zampini IS verticesIS,verticescomm; 67583301b35fSStefano Zampini PetscInt vsize,*idxs; 6759b96c3477SStefano Zampini 6760b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 67613301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 67623301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 67633301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 67643301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 67653301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6766b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 67677fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 6768441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 67693301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6770b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6771b96c3477SStefano Zampini } else { 6772b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6773b96c3477SStefano Zampini } 6774e4d548c7SStefano Zampini /* print some info */ 6775e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 6776e4d548c7SStefano Zampini IS vertices; 6777e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 6778e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6779e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 6780e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 6781e4d548c7SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 6782e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6783e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6784e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 6785e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 6786e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 6787e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6788e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6789e4d548c7SStefano Zampini } 6790b96c3477SStefano Zampini 6791b96c3477SStefano Zampini /* sub_schurs init */ 6792b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 6793b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 6794b334f244SStefano Zampini } 6795b334f244SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6796a64f4aa4SStefano Zampini 6797b96c3477SStefano Zampini /* free graph struct */ 679808122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6799b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6800b96c3477SStefano Zampini } 6801b96c3477SStefano Zampini PetscFunctionReturn(0); 6802b96c3477SStefano Zampini } 6803fa34dd3eSStefano Zampini 6804fa34dd3eSStefano Zampini #undef __FUNCT__ 6805fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6806fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6807fa34dd3eSStefano Zampini { 6808fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6809fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6810fa34dd3eSStefano Zampini PetscErrorCode ierr; 6811fa34dd3eSStefano Zampini 6812fa34dd3eSStefano Zampini PetscFunctionBegin; 6813fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6814fa34dd3eSStefano Zampini IS zerodiag = NULL; 68154f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6816fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 68174f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 681875c01103SStefano Zampini PetscReal norm; 6819fa34dd3eSStefano Zampini PetscInt i; 6820fa34dd3eSStefano Zampini 6821fa34dd3eSStefano Zampini /* B0 and B0_B */ 6822fa34dd3eSStefano Zampini if (zerodiag) { 6823fa34dd3eSStefano Zampini IS dummy; 6824fa34dd3eSStefano Zampini 68254f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 68264f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6827fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6828fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6829fa34dd3eSStefano Zampini } 6830fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6831fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6832fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6833fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6834fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6835fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6836fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6837fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6838fa34dd3eSStefano Zampini /* S_j */ 6839fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6840fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6841fa34dd3eSStefano Zampini 6842fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6843fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6844fa34dd3eSStefano Zampini /* continuous in primal space */ 6845fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6846fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6847fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6848fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 68494f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 68504f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6851fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6852fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6853fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6854fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6855fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6856fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6857fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6858fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6859fa34dd3eSStefano Zampini 6860fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6861fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6862fa34dd3eSStefano Zampini /* local with Schur */ 6863fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6864fa34dd3eSStefano Zampini if (zerodiag) { 6865fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 68664f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6867fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6868fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6869fa34dd3eSStefano Zampini } 6870fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6871fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6872fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6873fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6874fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6875fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6876fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6877fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6878fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6879fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6880fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6881fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6882fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6883fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6884fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6885fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6886fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6887fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6888fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6889fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6890fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6891fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6892fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6893fa34dd3eSStefano Zampini if (zerodiag) { 6894fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6895fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 68964f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6897fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6898fa34dd3eSStefano Zampini } 6899fa34dd3eSStefano Zampini /* BDDC */ 6900fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6901fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6902fa34dd3eSStefano Zampini 6903fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6904fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6905fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6906fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 69074f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 69084f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6909fa34dd3eSStefano Zampini } 69104f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6911fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6912fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6913fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6914fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6915fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6916fa34dd3eSStefano Zampini } 6917fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6918fa34dd3eSStefano Zampini } 6919