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 7a3df083aSStefano Zampini #undef __FUNCT__ 8*1f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 9*1f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 10*1f4df5f7SStefano Zampini { 11*1f4df5f7SStefano Zampini PetscErrorCode ierr; 12*1f4df5f7SStefano Zampini Vec local,global; 13*1f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 14*1f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 15*1f4df5f7SStefano Zampini 16*1f4df5f7SStefano Zampini PetscFunctionBegin; 17*1f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 18*1f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 19*1f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 20*1f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 21*1f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 22*1f4df5f7SStefano Zampini PetscInt i; 23*1f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 24*1f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 25*1f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 26*1f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 27*1f4df5f7SStefano Zampini } 28*1f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 29*1f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 30*1f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 31*1f4df5f7SStefano Zampini } 32*1f4df5f7SStefano Zampini } else { 33*1f4df5f7SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 34*1f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 35*1f4df5f7SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 36*1f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 37*1f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 38*1f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 39*1f4df5f7SStefano Zampini } 40*1f4df5f7SStefano Zampini } 41*1f4df5f7SStefano Zampini } 42*1f4df5f7SStefano Zampini 43*1f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 44*1f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 45*1f4df5f7SStefano Zampini } 46*1f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 47*1f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 48*1f4df5f7SStefano Zampini } 49*1f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 50*1f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 51*1f4df5f7SStefano Zampini } 52*1f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 53*1f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 54*1f4df5f7SStefano Zampini PetscFunctionReturn(0); 55*1f4df5f7SStefano Zampini } 56*1f4df5f7SStefano Zampini 57*1f4df5f7SStefano Zampini #undef __FUNCT__ 58a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 59a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 60a3df083aSStefano Zampini { 61a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 62a3df083aSStefano Zampini PetscErrorCode ierr; 63a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 64a3df083aSStefano Zampini 65a3df083aSStefano Zampini PetscFunctionBegin; 66a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 67a3df083aSStefano Zampini if (transpose) { 68a3df083aSStefano Zampini apply_right = ctx->apply_left; 69a3df083aSStefano Zampini apply_left = ctx->apply_right; 70a3df083aSStefano Zampini } else { 71a3df083aSStefano Zampini apply_right = ctx->apply_right; 72a3df083aSStefano Zampini apply_left = ctx->apply_left; 73a3df083aSStefano Zampini } 74a3df083aSStefano Zampini reset_x = PETSC_FALSE; 75a3df083aSStefano Zampini if (apply_right) { 76a3df083aSStefano Zampini const PetscScalar *ax; 77a3df083aSStefano Zampini PetscInt nl,i; 78a3df083aSStefano Zampini 79a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 80a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 81a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 82a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 83a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 84a3df083aSStefano Zampini PetscScalar sum,val; 85a3df083aSStefano Zampini const PetscInt *idxs; 86a3df083aSStefano Zampini PetscInt nz,j; 87a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 88a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 89a3df083aSStefano Zampini sum = 0.; 90a3df083aSStefano Zampini if (ctx->apply_p0) { 91a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 92a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 93a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 94a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 95a3df083aSStefano Zampini } 96a3df083aSStefano Zampini } else { 97a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 98a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 99a3df083aSStefano Zampini } 100a3df083aSStefano Zampini } 101a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 102a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 103a3df083aSStefano Zampini } 104a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 105a3df083aSStefano Zampini reset_x = PETSC_TRUE; 106a3df083aSStefano Zampini } 107a3df083aSStefano Zampini if (transpose) { 108a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 109a3df083aSStefano Zampini } else { 110a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 111a3df083aSStefano Zampini } 112a3df083aSStefano Zampini if (reset_x) { 113a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 114a3df083aSStefano Zampini } 115a3df083aSStefano Zampini if (apply_left) { 116a3df083aSStefano Zampini PetscScalar *ay; 117a3df083aSStefano Zampini PetscInt i; 118a3df083aSStefano Zampini 119a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 120a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 121a3df083aSStefano Zampini PetscScalar sum,val; 122a3df083aSStefano Zampini const PetscInt *idxs; 123a3df083aSStefano Zampini PetscInt nz,j; 124a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 125a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 126a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 127a3df083aSStefano Zampini if (ctx->apply_p0) { 128a3df083aSStefano Zampini sum = 0.; 129a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 130a3df083aSStefano Zampini sum += ay[idxs[j]]; 131a3df083aSStefano Zampini ay[idxs[j]] += val; 132a3df083aSStefano Zampini } 133a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 134a3df083aSStefano Zampini } else { 135a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 136a3df083aSStefano Zampini ay[idxs[j]] += val; 137a3df083aSStefano Zampini } 138a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 139a3df083aSStefano Zampini } 140a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 141a3df083aSStefano Zampini } 142a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 143a3df083aSStefano Zampini } 144a3df083aSStefano Zampini PetscFunctionReturn(0); 145a3df083aSStefano Zampini } 146a3df083aSStefano Zampini 147a3df083aSStefano Zampini #undef __FUNCT__ 148a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 149a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 150a3df083aSStefano Zampini { 151a3df083aSStefano Zampini PetscErrorCode ierr; 152a3df083aSStefano Zampini 153a3df083aSStefano Zampini PetscFunctionBegin; 154a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 155a3df083aSStefano Zampini PetscFunctionReturn(0); 156a3df083aSStefano Zampini } 157a3df083aSStefano Zampini 158a3df083aSStefano Zampini #undef __FUNCT__ 159a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 160a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 161a3df083aSStefano Zampini { 162a3df083aSStefano Zampini PetscErrorCode ierr; 163a3df083aSStefano Zampini 164a3df083aSStefano Zampini PetscFunctionBegin; 165a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 166a3df083aSStefano Zampini PetscFunctionReturn(0); 167a3df083aSStefano Zampini } 168a3df083aSStefano Zampini 169a3df083aSStefano Zampini #undef __FUNCT__ 170a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 171a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 172a3df083aSStefano Zampini { 173a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 174a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 175a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 176a3df083aSStefano Zampini PetscErrorCode ierr; 177a3df083aSStefano Zampini 178a3df083aSStefano Zampini PetscFunctionBegin; 179a3df083aSStefano Zampini if (!restore) { 1801dd7afcfSStefano Zampini Mat A_IB,A_BI; 181a3df083aSStefano Zampini PetscScalar *work; 182df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs->reuse_solver; 183a3df083aSStefano Zampini 1841dd7afcfSStefano Zampini if (pcbddc->benign_original_mat) { 1851dd7afcfSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 1861dd7afcfSStefano Zampini } 1871dd7afcfSStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) { 1881dd7afcfSStefano Zampini PetscFunctionReturn(0); 1891dd7afcfSStefano Zampini } 190a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 191a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 192a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 193a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 194a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 195a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 196a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 197a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 198a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 199a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 200a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 201a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 202059032f7SStefano Zampini if (reuse) { 203a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 2041dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 205059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 206059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 207059032f7SStefano Zampini PetscInt i; 208059032f7SStefano Zampini 209059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 210059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 211059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 212059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 213059032f7SStefano Zampini } 214059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 2151dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 216059032f7SStefano Zampini } 217a3df083aSStefano Zampini ctx->A = pcis->A_IB; 218a3df083aSStefano Zampini ctx->work = work; 219a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 220a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 221a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 222a3df083aSStefano Zampini pcis->A_IB = A_IB; 223a3df083aSStefano Zampini 224a3df083aSStefano Zampini /* A_BI as A_IB^T */ 225a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 226a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 227a3df083aSStefano Zampini pcis->A_BI = A_BI; 228a3df083aSStefano Zampini } else { 2291dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 2301dd7afcfSStefano Zampini PetscFunctionReturn(0); 2311dd7afcfSStefano Zampini } 232a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 233a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 234a3df083aSStefano Zampini pcis->A_IB = ctx->A; 2351dd7afcfSStefano Zampini ctx->A = NULL; 2361dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 2371dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 2381dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 2391dd7afcfSStefano Zampini if (ctx->free) { 240059032f7SStefano Zampini PetscInt i; 2411dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 242059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 243059032f7SStefano Zampini } 244059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 245059032f7SStefano Zampini } 246a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 247a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 248a3df083aSStefano Zampini } 249a3df083aSStefano Zampini PetscFunctionReturn(0); 250a3df083aSStefano Zampini } 251a3df083aSStefano Zampini 252a3df083aSStefano Zampini /* used just in bddc debug mode */ 253a3df083aSStefano Zampini #undef __FUNCT__ 254a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 255a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 256a3df083aSStefano Zampini { 257a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 258a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 259a3df083aSStefano Zampini Mat An; 260a3df083aSStefano Zampini PetscErrorCode ierr; 261a3df083aSStefano Zampini 262a3df083aSStefano Zampini PetscFunctionBegin; 263a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 264a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 265a3df083aSStefano Zampini if (is1) { 266a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 267a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 268a3df083aSStefano Zampini } else { 269a3df083aSStefano Zampini *B = An; 270a3df083aSStefano Zampini } 271a3df083aSStefano Zampini PetscFunctionReturn(0); 272a3df083aSStefano Zampini } 273a3df083aSStefano Zampini 2741cf9b237SStefano Zampini /* TODO: add reuse flag */ 2751cf9b237SStefano Zampini #undef __FUNCT__ 2761cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 2771cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 2781cf9b237SStefano Zampini { 2791cf9b237SStefano Zampini Mat Bt; 2801cf9b237SStefano Zampini PetscScalar *a,*bdata; 2811cf9b237SStefano Zampini const PetscInt *ii,*ij; 2821cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 2831cf9b237SStefano Zampini PetscBool flg_row; 2841cf9b237SStefano Zampini PetscErrorCode ierr; 2851cf9b237SStefano Zampini 2861cf9b237SStefano Zampini PetscFunctionBegin; 2871cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 2881cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 2891cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 2901cf9b237SStefano Zampini nnz = n; 2911cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 2921cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 2931cf9b237SStefano Zampini } 2941cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 2951cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 2961cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 2971cf9b237SStefano Zampini nnz = 0; 2981cf9b237SStefano Zampini bii[0] = 0; 2991cf9b237SStefano Zampini for (i=0;i<n;i++) { 3001cf9b237SStefano Zampini PetscInt j; 3011cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 3021cf9b237SStefano Zampini PetscScalar entry = a[j]; 3031cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 3041cf9b237SStefano Zampini bij[nnz] = ij[j]; 3051cf9b237SStefano Zampini bdata[nnz] = entry; 3061cf9b237SStefano Zampini nnz++; 3071cf9b237SStefano Zampini } 3081cf9b237SStefano Zampini } 3091cf9b237SStefano Zampini bii[i+1] = nnz; 3101cf9b237SStefano Zampini } 3111cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 3121cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 3131cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 3141cf9b237SStefano Zampini { 3151cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 3161cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 3171cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 3181cf9b237SStefano Zampini } 3191cf9b237SStefano Zampini *B = Bt; 3201cf9b237SStefano Zampini PetscFunctionReturn(0); 3211cf9b237SStefano Zampini } 3221cf9b237SStefano Zampini 323674ae819SStefano Zampini #undef __FUNCT__ 3244f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 3254f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 3264f1b2e48SStefano Zampini { 3274f1b2e48SStefano Zampini Mat B; 3284f1b2e48SStefano Zampini IS is_dummy,*cc_n; 3294f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 3304f1b2e48SStefano Zampini PCBDDCGraph graph; 3314f1b2e48SStefano Zampini PetscInt i,n; 3324f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 3334f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 3344f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 3354f1b2e48SStefano Zampini PetscErrorCode ierr; 3364f1b2e48SStefano Zampini 3374f1b2e48SStefano Zampini PetscFunctionBegin; 33863c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 33963c961adSStefano Zampini *ncc = 0; 34063c961adSStefano Zampini *cc = NULL; 34163c961adSStefano Zampini PetscFunctionReturn(0); 34263c961adSStefano Zampini } 3434f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 3444f1b2e48SStefano Zampini if (!isseqaij && filter) { 3451cf9b237SStefano Zampini PetscBool isseqdense; 3461cf9b237SStefano Zampini 3471cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 3481cf9b237SStefano Zampini if (!isseqdense) { 3494f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 3501cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 3511cf9b237SStefano Zampini PetscScalar *array; 3521cf9b237SStefano Zampini PetscReal chop=1.e-6; 3531cf9b237SStefano Zampini 3541cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 3551cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 3561cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 3571cf9b237SStefano Zampini for (i=0;i<n;i++) { 3581cf9b237SStefano Zampini PetscInt j; 3591cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 3601cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 3611cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 3621cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 3631cf9b237SStefano Zampini } 3641cf9b237SStefano Zampini } 3651cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 3669d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 3671cf9b237SStefano Zampini } 3684f1b2e48SStefano Zampini } else { 3694f1b2e48SStefano Zampini B = A; 3704f1b2e48SStefano Zampini } 3714f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3724f1b2e48SStefano Zampini 3734f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 3744f1b2e48SStefano Zampini if (filter) { 3754f1b2e48SStefano Zampini PetscScalar *data; 3764f1b2e48SStefano Zampini PetscInt j,cum; 3774f1b2e48SStefano Zampini 3784f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 3794f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 3804f1b2e48SStefano Zampini cum = 0; 3814f1b2e48SStefano Zampini for (i=0;i<n;i++) { 3824f1b2e48SStefano Zampini PetscInt t; 3834f1b2e48SStefano Zampini 3844f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 3854f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 3864f1b2e48SStefano Zampini continue; 3874f1b2e48SStefano Zampini } 3884f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 3894f1b2e48SStefano Zampini } 3904f1b2e48SStefano Zampini t = xadj_filtered[i]; 3914f1b2e48SStefano Zampini xadj_filtered[i] = cum; 3924f1b2e48SStefano Zampini cum += t; 3934f1b2e48SStefano Zampini } 3944f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 3954f1b2e48SStefano Zampini } else { 3964f1b2e48SStefano Zampini xadj_filtered = NULL; 3974f1b2e48SStefano Zampini adjncy_filtered = NULL; 3984f1b2e48SStefano Zampini } 3994f1b2e48SStefano Zampini 4004f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 4014f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 4024f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 4034f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4044f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 4054f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 4064f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 4074f1b2e48SStefano Zampini if (xadj_filtered) { 4084f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 4094f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 4104f1b2e48SStefano Zampini } else { 4114f1b2e48SStefano Zampini graph->xadj = xadj; 4124f1b2e48SStefano Zampini graph->adjncy = adjncy; 4134f1b2e48SStefano Zampini } 4144f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 4154f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 4164f1b2e48SStefano Zampini /* partial clean up */ 4174f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 4184f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4191cf9b237SStefano Zampini if (A != B) { 4204f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4214f1b2e48SStefano Zampini } 4224f1b2e48SStefano Zampini 4234f1b2e48SStefano Zampini /* get back data */ 4241cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 4251cf9b237SStefano Zampini if (cc) { 4264f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 4274f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 4284f1b2e48SStefano 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); 4294f1b2e48SStefano Zampini } 4304f1b2e48SStefano Zampini *cc = cc_n; 4311cf9b237SStefano Zampini } 4324f1b2e48SStefano Zampini /* clean up graph */ 4334f1b2e48SStefano Zampini graph->xadj = 0; 4344f1b2e48SStefano Zampini graph->adjncy = 0; 4354f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 4364f1b2e48SStefano Zampini PetscFunctionReturn(0); 4374f1b2e48SStefano Zampini } 4384f1b2e48SStefano Zampini 4394f1b2e48SStefano Zampini #undef __FUNCT__ 4405408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 4415408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 4425408967cSStefano Zampini { 4435408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4445408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 445dee84bffSStefano Zampini IS dirIS = NULL; 4464f1b2e48SStefano Zampini PetscInt i; 4475408967cSStefano Zampini PetscErrorCode ierr; 4485408967cSStefano Zampini 4495408967cSStefano Zampini PetscFunctionBegin; 450dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 4515408967cSStefano Zampini if (zerodiag) { 4525408967cSStefano Zampini Mat A; 4535408967cSStefano Zampini Vec vec3_N; 4545408967cSStefano Zampini PetscScalar *vals; 4555408967cSStefano Zampini const PetscInt *idxs; 456d12d3064SStefano Zampini PetscInt nz,*count; 4575408967cSStefano Zampini 4585408967cSStefano Zampini /* p0 */ 4595408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 4605408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 4615408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 4625408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 4634f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 4645408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4655408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4665408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4675408967cSStefano Zampini /* v_I */ 4685408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 4695408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 4705408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4715408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 4725408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 4735408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 4745408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4755408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 4765408967cSStefano Zampini if (dirIS) { 4775408967cSStefano Zampini PetscInt n; 4785408967cSStefano Zampini 4795408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 4805408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 4815408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 4825408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4835408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 4845408967cSStefano Zampini } 4855408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 4865408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 4875408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 4885408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 4895408967cSStefano Zampini ierr = MatISGetLocalMat(pc->mat,&A);CHKERRQ(ierr); 4905408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 4915408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 492fbfcb133SStefano Zampini if (PetscAbsScalar(vals[0]) > 1.e-1) { 493b9b0e38cSStefano 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])); 4945408967cSStefano Zampini } 4955408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4965408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 497d12d3064SStefano Zampini 498d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 499d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 500d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 501d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 502d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 503d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 504d4d8cf7bSStefano Zampini for (i=0;i<nz;i++) { 505d12d3064SStefano Zampini if (count[idxs[i]]) { 506d12d3064SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 507d12d3064SStefano Zampini } 508d4d8cf7bSStefano Zampini } 509d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 510d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 5115408967cSStefano Zampini } 512dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 5135408967cSStefano Zampini 5145408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 5155408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 5164f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 5175408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 5184f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 5195408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 5204f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 5214f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 5224f1b2e48SStefano 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); 5234f1b2e48SStefano Zampini } 5245408967cSStefano Zampini } 5255408967cSStefano Zampini PetscFunctionReturn(0); 5265408967cSStefano Zampini } 5275408967cSStefano Zampini 5285408967cSStefano Zampini #undef __FUNCT__ 529339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 530339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 531339f8db1SStefano Zampini { 532339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5334f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 534b0f5fe93SStefano Zampini PetscInt nz,n; 535*1f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 5364f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 537339f8db1SStefano Zampini PetscErrorCode ierr; 538339f8db1SStefano Zampini 539339f8db1SStefano Zampini PetscFunctionBegin; 5409f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 5419f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 542a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 543a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 544a3df083aSStefano Zampini } 545a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 546a3df083aSStefano Zampini pcbddc->benign_n = 0; 5474f1b2e48SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures" 5484f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 5494f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 5504f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 5514f1b2e48SStefano Zampini since the local Schur complements are SPD 5524f1b2e48SStefano Zampini */ 5534f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 5544f1b2e48SStefano Zampini have_null = PETSC_TRUE; 55540fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 5564f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 5574f1b2e48SStefano Zampini 5584f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 5594f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 5604f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 5614f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 562ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 56340fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 56440fa8d13SStefano Zampini if (!sorted) { 56540fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 56640fa8d13SStefano Zampini } 56740fa8d13SStefano Zampini } else { 56840fa8d13SStefano Zampini pressures = NULL; 56940fa8d13SStefano Zampini } 57097d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 57197d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 57227b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 57397d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 574339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 575339f8db1SStefano Zampini if (!sorted) { 576339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 577339f8db1SStefano Zampini } 578339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5794f1b2e48SStefano Zampini if (!nz) { 5804f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 5814f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 58240fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 58340fa8d13SStefano Zampini } 5844f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 5854f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 5864f1b2e48SStefano Zampini zerodiag_subs = NULL; 5874f1b2e48SStefano Zampini pcbddc->benign_n = 0; 588*1f4df5f7SStefano Zampini n_interior_dofs = 0; 589*1f4df5f7SStefano Zampini interior_dofs = NULL; 590*1f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 591*1f4df5f7SStefano Zampini PetscInt n,i,j; 592*1f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 593*1f4df5f7SStefano Zampini PetscInt *iwork; 594*1f4df5f7SStefano Zampini 595*1f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 596*1f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 597*1f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 598*1f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 599*1f4df5f7SStefano Zampini for (i=0;i<n_neigh;i++) 600*1f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 601*1f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 602*1f4df5f7SStefano Zampini for (i=0;i<n;i++) 603*1f4df5f7SStefano Zampini if (!iwork[i]) 604*1f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 605*1f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 606*1f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 607*1f4df5f7SStefano Zampini } 6084f1b2e48SStefano Zampini if (has_null_pressures) { 6094f1b2e48SStefano Zampini IS *subs; 610*1f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 611*1f4df5f7SStefano Zampini const PetscInt *idxs; 612*1f4df5f7SStefano Zampini PetscScalar *array; 613*1f4df5f7SStefano Zampini Vec *work; 614*1f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 6154f1b2e48SStefano Zampini 6164f1b2e48SStefano Zampini subs = pcbddc->local_subs; 6174f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 618*1f4df5f7SStefano 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) */ 619*1f4df5f7SStefano Zampini if (pcbddc->current_level) { 620*1f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 621*1f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 622*1f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 623*1f4df5f7SStefano Zampini /* work[0] = 1_p */ 624*1f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 625*1f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 626*1f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 627*1f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 628*1f4df5f7SStefano Zampini /* work[0] = 1_v */ 629*1f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 630*1f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 631*1f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 632*1f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 633*1f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 634*1f4df5f7SStefano Zampini } 6354f1b2e48SStefano Zampini if (nsubs > 1) { 6364f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 6374f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 6384f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 6394f1b2e48SStefano Zampini IS t_zerodiag_subs; 6404f1b2e48SStefano Zampini PetscInt nl; 6414f1b2e48SStefano Zampini 6424f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 6434f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 6444f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 6454f1b2e48SStefano Zampini if (nl) { 6464f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 6474f1b2e48SStefano Zampini 648*1f4df5f7SStefano Zampini if (pcbddc->current_level) { 649*1f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 650*1f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 651*1f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 652*1f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 653*1f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 654*1f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 655*1f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 656*1f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 657*1f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 658*1f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 659*1f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 660*1f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 661*1f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 662*1f4df5f7SStefano Zampini valid = PETSC_FALSE; 663*1f4df5f7SStefano Zampini break; 664*1f4df5f7SStefano Zampini } 665*1f4df5f7SStefano Zampini } 666*1f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 667*1f4df5f7SStefano Zampini } 668*1f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 669*1f4df5f7SStefano Zampini IS t_bc; 670*1f4df5f7SStefano Zampini PetscInt nzb; 671*1f4df5f7SStefano Zampini 672*1f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 673*1f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 674*1f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 675*1f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 676*1f4df5f7SStefano Zampini } 677*1f4df5f7SStefano Zampini if (valid && pressures) { 6784f1b2e48SStefano Zampini IS t_pressure_subs; 6794f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 6804f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 6814f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 6824f1b2e48SStefano Zampini } 6834f1b2e48SStefano Zampini if (valid) { 6844f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 6854f1b2e48SStefano Zampini pcbddc->benign_n++; 6864f1b2e48SStefano Zampini } else { 6874f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 6884f1b2e48SStefano Zampini } 6894f1b2e48SStefano Zampini } 6904f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 6914f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 6924f1b2e48SStefano Zampini } 6934f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 6944f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 695*1f4df5f7SStefano Zampini 696*1f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 697*1f4df5f7SStefano Zampini PetscInt nzb; 698*1f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 699*1f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 700*1f4df5f7SStefano Zampini } 701*1f4df5f7SStefano Zampini if (valid && pressures) { 7024f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 7034f1b2e48SStefano Zampini } 704*1f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 705*1f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 706*1f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 707*1f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 708*1f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 709*1f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 710*1f4df5f7SStefano Zampini valid = PETSC_FALSE; 711*1f4df5f7SStefano Zampini break; 712*1f4df5f7SStefano Zampini } 713*1f4df5f7SStefano Zampini } 714*1f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 715*1f4df5f7SStefano Zampini } 7164f1b2e48SStefano Zampini if (valid) { 7174f1b2e48SStefano Zampini pcbddc->benign_n = 1; 718ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 7194f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 7204f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 7214f1b2e48SStefano Zampini } 7224f1b2e48SStefano Zampini } 723*1f4df5f7SStefano Zampini if (pcbddc->current_level) { 724*1f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 7254f1b2e48SStefano Zampini } 726*1f4df5f7SStefano Zampini } 727*1f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 7284f1b2e48SStefano Zampini 7294f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 730b9b0e38cSStefano Zampini PetscInt n; 731b9b0e38cSStefano Zampini 7324f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 7334f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 734b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 735b9b0e38cSStefano Zampini if (n) { 7364f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 7374f1b2e48SStefano Zampini have_null = PETSC_FALSE; 7384f1b2e48SStefano Zampini } 739b9b0e38cSStefano Zampini } 7404f1b2e48SStefano Zampini 7414f1b2e48SStefano Zampini /* final check for null pressures */ 7424f1b2e48SStefano Zampini if (zerodiag && pressures) { 7434f1b2e48SStefano Zampini PetscInt nz,np; 7444f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 7454f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 7464f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 7474f1b2e48SStefano Zampini } 7484f1b2e48SStefano Zampini 7494f1b2e48SStefano Zampini if (recompute_zerodiag) { 7504f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 7514f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 7524f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 7534f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 7544f1b2e48SStefano Zampini } else { 7554f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 7564f1b2e48SStefano Zampini 7574f1b2e48SStefano Zampini nzn = 0; 7584f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 7594f1b2e48SStefano Zampini PetscInt ns; 7604f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 7614f1b2e48SStefano Zampini nzn += ns; 7624f1b2e48SStefano Zampini } 7634f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 7644f1b2e48SStefano Zampini nzn = 0; 7654f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 7664f1b2e48SStefano Zampini PetscInt ns,*idxs; 7674f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 7684f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 7694f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 7704f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 7714f1b2e48SStefano Zampini nzn += ns; 7724f1b2e48SStefano Zampini } 7734f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 7744f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 7754f1b2e48SStefano Zampini } 7764f1b2e48SStefano Zampini have_null = PETSC_FALSE; 7774f1b2e48SStefano Zampini } 7784f1b2e48SStefano Zampini 779b3afcdbeSStefano Zampini /* no-net-flux */ 780b3afcdbeSStefano Zampini if (pcbddc->benign_compute_nonetflux) { 781b3afcdbeSStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 782b3afcdbeSStefano Zampini MatNullSpace near_null_space; 783b3afcdbeSStefano Zampini ISLocalToGlobalMapping rmap; 784b3afcdbeSStefano Zampini Vec quad_vec; 785b3afcdbeSStefano Zampini PetscScalar *pvals; 786b3afcdbeSStefano Zampini PetscInt i,np,*dummyins; 787*1f4df5f7SStefano Zampini IS isused = NULL; 788*1f4df5f7SStefano Zampini PetscBool participate = PETSC_TRUE; 789b3afcdbeSStefano Zampini 790b3afcdbeSStefano Zampini /* create vector to hold quadrature weights */ 791b3afcdbeSStefano Zampini ierr = MatCreateVecs(pc->pmat,&quad_vec,NULL);CHKERRQ(ierr); 792b3afcdbeSStefano Zampini ierr = VecSet(quad_vec,0.0);CHKERRQ(ierr); 793b3afcdbeSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&rmap,NULL);CHKERRQ(ierr); 794b3afcdbeSStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vec,rmap);CHKERRQ(ierr); 795b3afcdbeSStefano Zampini 796b3afcdbeSStefano Zampini /* compute B^{(i)T} * 1_p */ 797b3afcdbeSStefano Zampini np = 0; 798*1f4df5f7SStefano Zampini if (pressures) { 799*1f4df5f7SStefano Zampini isused = pressures; 800*1f4df5f7SStefano Zampini } else { 801*1f4df5f7SStefano Zampini isused = zerodiag; 802*1f4df5f7SStefano Zampini } 803*1f4df5f7SStefano Zampini if (isused) { 804*1f4df5f7SStefano Zampini ierr = ISGetLocalSize(isused,&np);CHKERRQ(ierr); 805b3afcdbeSStefano Zampini } 806b3afcdbeSStefano Zampini ierr = PetscMalloc1(np,&pvals);CHKERRQ(ierr); 807b3afcdbeSStefano Zampini for (i=0;i<np;i++) pvals[i] = 1.; 808b3afcdbeSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 809b3afcdbeSStefano Zampini if (np) { 810b3afcdbeSStefano Zampini const PetscInt *pidxs; 811b3afcdbeSStefano Zampini 812*1f4df5f7SStefano Zampini if (isused) { 813*1f4df5f7SStefano Zampini ierr = ISGetIndices(isused,&pidxs);CHKERRQ(ierr); 814b3afcdbeSStefano Zampini } 815b3afcdbeSStefano Zampini ierr = VecSetValues(matis->x,np,pidxs,pvals,INSERT_VALUES);CHKERRQ(ierr); 816*1f4df5f7SStefano Zampini if (isused) { 817*1f4df5f7SStefano Zampini ierr = ISRestoreIndices(isused,&pidxs);CHKERRQ(ierr); 818b3afcdbeSStefano Zampini } 819b3afcdbeSStefano Zampini } 820b3afcdbeSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 821b3afcdbeSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 822b3afcdbeSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 823b3afcdbeSStefano Zampini ierr = PetscFree(pvals);CHKERRQ(ierr); 824*1f4df5f7SStefano Zampini if (!isused) participate = PETSC_FALSE; 825b3afcdbeSStefano Zampini /* decide which of the sharing ranks (per dof) has to insert the values (should just be a matter of having a different orientation) */ 826b3afcdbeSStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 827daf8a457SStefano Zampini for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = -1; 828*1f4df5f7SStefano Zampini for (i=0;i<matis->sf->nleaves;i++) 829*1f4df5f7SStefano Zampini if (participate) matis->sf_leafdata[i] = PetscGlobalRank; 830*1f4df5f7SStefano Zampini else matis->sf_leafdata[i] = -1; 831*1f4df5f7SStefano Zampini 832b3afcdbeSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_MAX);CHKERRQ(ierr); 833b3afcdbeSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_MAX);CHKERRQ(ierr); 834b3afcdbeSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 835b3afcdbeSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 836b3afcdbeSStefano Zampini ierr = VecGetArray(matis->y,&pvals);CHKERRQ(ierr); 837daf8a457SStefano Zampini for (i=0;i<matis->sf->nleaves;i++) { 838b3afcdbeSStefano Zampini if (PetscGlobalRank != matis->sf_leafdata[i]) { 839b3afcdbeSStefano Zampini pvals[i] = 0.; 840b3afcdbeSStefano Zampini } 841b3afcdbeSStefano Zampini } 842daf8a457SStefano Zampini ierr = PetscMalloc1(matis->sf->nleaves,&dummyins);CHKERRQ(ierr); 843daf8a457SStefano Zampini for (i=0;i<matis->sf->nleaves;i++) dummyins[i] = i; 844daf8a457SStefano Zampini ierr = VecSetValuesLocal(quad_vec,matis->sf->nleaves,dummyins,pvals,ADD_VALUES);CHKERRQ(ierr); 845b3afcdbeSStefano Zampini ierr = VecRestoreArray(matis->y,&pvals);CHKERRQ(ierr); 846b3afcdbeSStefano Zampini ierr = PetscFree(dummyins);CHKERRQ(ierr); 847b3afcdbeSStefano Zampini 848b3afcdbeSStefano Zampini /* assembly quadrature vec and attach near null space to pmat */ 849b3afcdbeSStefano Zampini ierr = VecAssemblyBegin(quad_vec);CHKERRQ(ierr); 850b3afcdbeSStefano Zampini ierr = VecAssemblyEnd(quad_vec);CHKERRQ(ierr); 851b3afcdbeSStefano Zampini ierr = VecNormalize(quad_vec,NULL);CHKERRQ(ierr); 852b3afcdbeSStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)pc),PETSC_FALSE,1,&quad_vec,&near_null_space);CHKERRQ(ierr); 853b3afcdbeSStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 854b3afcdbeSStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,near_null_space);CHKERRQ(ierr); 855b3afcdbeSStefano Zampini ierr = MatNullSpaceDestroy(&near_null_space);CHKERRQ(ierr); 856b3afcdbeSStefano Zampini } 857b3afcdbeSStefano Zampini 858b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 8594f1b2e48SStefano Zampini if (has_null_pressures) { 8604f1b2e48SStefano Zampini IS zerodiagc; 8614f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 8624f1b2e48SStefano Zampini PetscInt i,s,*nnz; 8634f1b2e48SStefano Zampini 8644f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 865339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 866339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 867339f8db1SStefano Zampini /* local change of basis for pressures */ 868339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 86997d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 870339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 871339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 872339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 8734f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 8744f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 8754f1b2e48SStefano Zampini PetscInt nzs,j; 8764f1b2e48SStefano Zampini 8774f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 8784f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 8794f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 8804f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 8814f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 8824f1b2e48SStefano Zampini } 883339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 884339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 885339f8db1SStefano Zampini /* set identity on velocities */ 886339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 887339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 888339f8db1SStefano Zampini } 8894f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 8904f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 8919f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 8924f1b2e48SStefano 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); 893339f8db1SStefano Zampini /* set change on pressures */ 8944f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 8954f1b2e48SStefano Zampini PetscScalar *array; 8964f1b2e48SStefano Zampini PetscInt nzs; 8974f1b2e48SStefano Zampini 8984f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 8994f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 9004f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 901339f8db1SStefano Zampini PetscScalar vals[2]; 902339f8db1SStefano Zampini PetscInt cols[2]; 903339f8db1SStefano Zampini 904339f8db1SStefano Zampini cols[0] = idxs[i]; 9054f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 906339f8db1SStefano Zampini vals[0] = 1.; 907b0f5fe93SStefano Zampini vals[1] = 1.; 9084f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 909339f8db1SStefano Zampini } 9104f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 9114f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 9124f1b2e48SStefano Zampini array[nzs-1] = 1.; 9134f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 9144f1b2e48SStefano Zampini /* store local idxs for p0 */ 9154f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 9164f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 917339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 9184f1b2e48SStefano Zampini } 919339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 920339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 921a3df083aSStefano Zampini /* project if needed */ 922a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 9231dd7afcfSStefano Zampini Mat M; 9241dd7afcfSStefano Zampini 9251dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 926339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 9271dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 9281dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 929a3df083aSStefano Zampini } 9304f1b2e48SStefano Zampini /* store global idxs for p0 */ 9314f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 932339f8db1SStefano Zampini } 933ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 9344f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 935b0f5fe93SStefano Zampini 936b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 937b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 93827b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 93927b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 940339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 941339f8db1SStefano Zampini PetscFunctionReturn(0); 942339f8db1SStefano Zampini } 943339f8db1SStefano Zampini 944339f8db1SStefano Zampini #undef __FUNCT__ 945015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 946015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 947efc2fbd9SStefano Zampini { 948efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 949de9d7bd0SStefano Zampini PetscScalar *array; 950efc2fbd9SStefano Zampini PetscErrorCode ierr; 951efc2fbd9SStefano Zampini 952efc2fbd9SStefano Zampini PetscFunctionBegin; 953efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 954efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 9554f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 956efc2fbd9SStefano Zampini } 957de9d7bd0SStefano Zampini if (get) { 958efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 9594f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 9604f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 961efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 962de9d7bd0SStefano Zampini } else { 963de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 964de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 965de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 966de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 967efc2fbd9SStefano Zampini } 968efc2fbd9SStefano Zampini PetscFunctionReturn(0); 969efc2fbd9SStefano Zampini } 970efc2fbd9SStefano Zampini 971efc2fbd9SStefano Zampini #undef __FUNCT__ 972c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 973c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 974c263805aSStefano Zampini { 975c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 976c263805aSStefano Zampini PetscErrorCode ierr; 977c263805aSStefano Zampini 978c263805aSStefano Zampini PetscFunctionBegin; 979c263805aSStefano Zampini /* TODO: add error checking 980c263805aSStefano Zampini - avoid nested pop (or push) calls. 981c263805aSStefano Zampini - cannot push before pop. 9821c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 983c263805aSStefano Zampini */ 9844f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 985efc2fbd9SStefano Zampini PetscFunctionReturn(0); 986efc2fbd9SStefano Zampini } 987c263805aSStefano Zampini if (pop) { 988a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 9894f1b2e48SStefano Zampini IS is_p0; 9904f1b2e48SStefano Zampini MatReuse reuse; 991c263805aSStefano Zampini 992c263805aSStefano Zampini /* extract B_0 */ 9934f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 9944f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 9954f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 9964f1b2e48SStefano Zampini } 9974f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 9984f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 999c263805aSStefano Zampini /* remove rows and cols from local problem */ 1000c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 100197d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 10024f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 10034f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 1004a3df083aSStefano Zampini } else { 1005a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1006a3df083aSStefano Zampini PetscScalar *vals; 1007a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 1008a3df083aSStefano Zampini 1009a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 1010a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 1011a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 10120b5adadeSStefano Zampini PetscInt *nnz; 1013a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 1014a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 1015a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1016331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 1017331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1018331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 1019331e053bSStefano Zampini nnz[i] = n - nnz[i]; 1020331e053bSStefano Zampini } 1021331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 1022331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1023331e053bSStefano Zampini } 1024a3df083aSStefano Zampini 1025a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1026a3df083aSStefano Zampini PetscScalar *array; 1027a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 1028a3df083aSStefano Zampini 1029a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 1030a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1031a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1032a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 1033a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1034a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 1035a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 1036a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 1037a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 1038a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 1039a3df083aSStefano Zampini cum = 0; 1040a3df083aSStefano Zampini for (j=0;j<n;j++) { 104122db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 1042a3df083aSStefano Zampini vals[cum] = array[j]; 1043a3df083aSStefano Zampini idxs_ins[cum] = j; 1044a3df083aSStefano Zampini cum++; 1045a3df083aSStefano Zampini } 1046a3df083aSStefano Zampini } 1047a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 1048a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 1049a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1050a3df083aSStefano Zampini } 1051a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1052a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1053a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 1054a3df083aSStefano Zampini } 1055c263805aSStefano Zampini } else { /* push */ 1056a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 10574f1b2e48SStefano Zampini PetscInt i; 10584f1b2e48SStefano Zampini 10594f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 10604f1b2e48SStefano Zampini PetscScalar *B0_vals; 10614f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 10624f1b2e48SStefano Zampini 10634f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 10644f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 10657b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 10664f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 10674f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 10684f1b2e48SStefano Zampini } 1069c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1070c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1071a3df083aSStefano Zampini } else { 1072a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 1073a3df083aSStefano Zampini } 1074c263805aSStefano Zampini } 1075c263805aSStefano Zampini PetscFunctionReturn(0); 1076c263805aSStefano Zampini } 1077c263805aSStefano Zampini 1078c263805aSStefano Zampini #undef __FUNCT__ 1079b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 108008122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 1081b1b3d7a2SStefano Zampini { 1082b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 108308122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 108408122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 108508122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 108608122e43SStefano Zampini PetscScalar *work,lwork; 108708122e43SStefano Zampini PetscScalar *St,*S,*eigv; 108808122e43SStefano Zampini PetscScalar *Sarray,*Starray; 108908122e43SStefano Zampini PetscReal *eigs,thresh; 10901b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 1091f6f667cfSStefano Zampini PetscBool allocated_S_St; 109208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 109308122e43SStefano Zampini PetscReal *rwork; 109408122e43SStefano Zampini #endif 1095b1b3d7a2SStefano Zampini PetscErrorCode ierr; 1096b1b3d7a2SStefano Zampini 1097b1b3d7a2SStefano Zampini PetscFunctionBegin; 1098af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 1099af25d912SStefano 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); 110006a4e24aSStefano Zampini 1101fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1102fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1103fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1104fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 11051575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1106fd14bc51SStefano Zampini } 1107fd14bc51SStefano Zampini 1108e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 1109e496cd5dSStefano 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); 1110e496cd5dSStefano Zampini } 1111e496cd5dSStefano Zampini 111208122e43SStefano Zampini /* max size of subsets */ 111308122e43SStefano Zampini mss = 0; 111408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 111508122e43SStefano Zampini PetscInt subset_size; 1116862806e4SStefano Zampini 111708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 111808122e43SStefano Zampini mss = PetscMax(mss,subset_size); 111908122e43SStefano Zampini } 112008122e43SStefano Zampini 112108122e43SStefano Zampini /* min/max and threshold */ 112208122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 1123f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 112408122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 1125f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 1126f6f667cfSStefano Zampini if (nmin) { 1127f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 1128f6f667cfSStefano Zampini } 112908122e43SStefano Zampini 113008122e43SStefano Zampini /* allocate lapack workspace */ 113108122e43SStefano Zampini cum = cum2 = 0; 113208122e43SStefano Zampini maxneigs = 0; 113308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 113408122e43SStefano Zampini PetscInt n,subset_size; 1135f6f667cfSStefano Zampini 113608122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 113708122e43SStefano Zampini n = PetscMin(subset_size,nmax); 11389162d606SStefano Zampini cum += subset_size; 11399162d606SStefano Zampini cum2 += subset_size*n; 114008122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 114108122e43SStefano Zampini } 114208122e43SStefano Zampini if (mss) { 11439ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 114408122e43SStefano Zampini PetscBLASInt B_itype = 1; 114508122e43SStefano Zampini PetscBLASInt B_N = mss; 11464c6709b3SStefano Zampini PetscReal zero = 0.0; 11474c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 114808122e43SStefano Zampini 114908122e43SStefano Zampini B_lwork = -1; 115008122e43SStefano Zampini S = NULL; 115108122e43SStefano Zampini St = NULL; 1152a58a30b4SStefano Zampini eigs = NULL; 1153a58a30b4SStefano Zampini eigv = NULL; 1154a58a30b4SStefano Zampini B_iwork = NULL; 1155a58a30b4SStefano Zampini B_ifail = NULL; 1156d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1157d1710679SStefano Zampini rwork = NULL; 1158d1710679SStefano Zampini #endif 11598bec7fa6SStefano Zampini thresh = 1.0; 116008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 116108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 116208122e43SStefano 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)); 116308122e43SStefano Zampini #else 116408122e43SStefano 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)); 116508122e43SStefano Zampini #endif 116608122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 116708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 116808122e43SStefano Zampini } else { 116908122e43SStefano Zampini /* TODO */ 117008122e43SStefano Zampini } 117108122e43SStefano Zampini } else { 117208122e43SStefano Zampini lwork = 0; 117308122e43SStefano Zampini } 117408122e43SStefano Zampini 117508122e43SStefano Zampini nv = 0; 1176d62866d3SStefano 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) */ 1177d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 117808122e43SStefano Zampini } 11794c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 1180f6f667cfSStefano Zampini if (allocated_S_St) { 1181f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 1182f6f667cfSStefano Zampini } 1183f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 118408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 118508122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 118608122e43SStefano Zampini #endif 11879162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 11889162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 11899162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 119008122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 11919162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 119208122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 119308122e43SStefano Zampini 119408122e43SStefano Zampini maxneigs = 0; 119572b8c272SStefano Zampini cum = cumarray = 0; 11969162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 11979162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 1198d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 119908122e43SStefano Zampini const PetscInt *idxs; 120008122e43SStefano Zampini 1201d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 120208122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 120308122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 120408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 120508122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 12069162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 12079162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 120808122e43SStefano Zampini } 1209d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 121008122e43SStefano Zampini } 121108122e43SStefano Zampini 121208122e43SStefano Zampini if (mss) { /* multilevel */ 121308122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 121408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 121508122e43SStefano Zampini } 121608122e43SStefano Zampini 1217ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 121808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 121908122e43SStefano Zampini const PetscInt *idxs; 12209d54b7f4SStefano Zampini PetscReal upper,lower; 1221862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 122208122e43SStefano Zampini PetscBLASInt B_N; 1223aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 122408122e43SStefano Zampini 12259d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 12269d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 12279d54b7f4SStefano Zampini lower = thresh; 12289d54b7f4SStefano Zampini } else { 12299d54b7f4SStefano Zampini upper = 1./thresh; 12309d54b7f4SStefano Zampini lower = 0.; 12319d54b7f4SStefano Zampini } 1232862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 1233ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 1234f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 1235f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 12369ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 1237aff50787SStefano Zampini PetscInt j,k; 1238aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 1239aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 1240aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 124108122e43SStefano Zampini } 124208122e43SStefano Zampini for (j=0;j<subset_size;j++) { 1243aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 1244aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 1245aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 1246aff50787SStefano Zampini } 124708122e43SStefano Zampini } 124808122e43SStefano Zampini } else { 124908122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 125008122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 125108122e43SStefano Zampini } 12528bec7fa6SStefano Zampini } else { 1253f6f667cfSStefano Zampini S = Sarray + cumarray; 1254f6f667cfSStefano Zampini St = Starray + cumarray; 12558bec7fa6SStefano Zampini } 1256aff50787SStefano Zampini /* see if we can save some work */ 1257b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 1258aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1259aff50787SStefano Zampini } 1260aff50787SStefano Zampini 1261b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 1262aff50787SStefano Zampini B_neigs = 0; 1263aff50787SStefano Zampini } else { 12649ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 126508122e43SStefano Zampini PetscBLASInt B_itype = 1; 1266f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 12674c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 12689552c7c7SStefano Zampini PetscInt nmin_s; 1269b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 127008122e43SStefano Zampini 1271fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 12728bec7fa6SStefano 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]]); 1273fd14bc51SStefano Zampini } 1274d16cbb6bSStefano Zampini 1275b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 1276b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 1277b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 1278b7ab4a40SStefano Zampini } 1279b7ab4a40SStefano Zampini 128008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1281b7ab4a40SStefano Zampini if (compute_range) { 1282d16cbb6bSStefano Zampini 1283d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 128408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 12859d54b7f4SStefano 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)); 128608122e43SStefano Zampini #else 12879d54b7f4SStefano 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)); 128808122e43SStefano Zampini #endif 1289b7ab4a40SStefano Zampini } else if (!same_data) { 1290d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1291d16cbb6bSStefano Zampini B_IL = 1; 1292d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 12939d54b7f4SStefano 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)); 1294d16cbb6bSStefano Zampini #else 12959d54b7f4SStefano 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)); 1296d16cbb6bSStefano Zampini #endif 1297b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 1298b7ab4a40SStefano Zampini PetscInt k; 1299b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 1300b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 1301b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 1302b7ab4a40SStefano Zampini nmin = nmax; 1303b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 1304b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 1305b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 1306b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 1307b7ab4a40SStefano Zampini } 1308d16cbb6bSStefano Zampini } 130908122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 131008122e43SStefano Zampini if (B_ierr) { 13116c4ed002SBarry 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); 13126c4ed002SBarry 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); 13136c4ed002SBarry 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); 131408122e43SStefano Zampini } 131508122e43SStefano Zampini 131608122e43SStefano Zampini if (B_neigs > nmax) { 1317fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1318fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1319fd14bc51SStefano Zampini } 13209d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 132108122e43SStefano Zampini B_neigs = nmax; 132208122e43SStefano Zampini } 132308122e43SStefano Zampini 13249552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 13259552c7c7SStefano Zampini if (B_neigs < nmin_s) { 132608122e43SStefano Zampini PetscBLASInt B_neigs2; 132708122e43SStefano Zampini 13289d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1329f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 13309d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 13319d54b7f4SStefano Zampini } else { 13329d54b7f4SStefano Zampini B_IL = B_neigs + 1; 13339d54b7f4SStefano Zampini B_IU = nmin_s; 13349d54b7f4SStefano Zampini } 1335fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1336fd14bc51SStefano 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); 1337fd14bc51SStefano Zampini } 13389ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 133908122e43SStefano Zampini PetscInt j; 134008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 134108122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 134208122e43SStefano Zampini } 134308122e43SStefano Zampini for (j=0;j<subset_size;j++) { 134408122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 134508122e43SStefano Zampini } 134608122e43SStefano Zampini } else { 134708122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 134808122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 134908122e43SStefano Zampini } 135008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 135108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 13529d54b7f4SStefano 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)); 135308122e43SStefano Zampini #else 13549d54b7f4SStefano 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)); 135508122e43SStefano Zampini #endif 135608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 135708122e43SStefano Zampini B_neigs += B_neigs2; 135808122e43SStefano Zampini } 135908122e43SStefano Zampini if (B_ierr) { 13606c4ed002SBarry 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); 13616c4ed002SBarry 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); 13626c4ed002SBarry 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); 136308122e43SStefano Zampini } 1364fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1365ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 136608122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 136708122e43SStefano Zampini if (eigs[j] == 0.0) { 1368ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 136908122e43SStefano Zampini } else { 13709d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1371ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 13729d54b7f4SStefano Zampini } else { 13739d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 13749d54b7f4SStefano Zampini } 1375fd14bc51SStefano Zampini } 137608122e43SStefano Zampini } 137708122e43SStefano Zampini } 137808122e43SStefano Zampini } else { 137908122e43SStefano Zampini /* TODO */ 138008122e43SStefano Zampini } 1381aff50787SStefano Zampini } 13826c3e6151SStefano Zampini /* change the basis back to the original one */ 13836c3e6151SStefano Zampini if (sub_schurs->change) { 138472b8c272SStefano Zampini Mat change,phi,phit; 13856c3e6151SStefano Zampini 13866c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 13876c3e6151SStefano Zampini PetscInt ii; 13886c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 13896c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 13906c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 13916c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 13926c3e6151SStefano Zampini } 13936c3e6151SStefano Zampini } 13946c3e6151SStefano Zampini } 139572b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 13966c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 139772b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 13986c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 13996c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 14006c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 14016c3e6151SStefano Zampini } 14028bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 14038bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 14049162d606SStefano Zampini if (B_neigs) { 14059162d606SStefano 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); 1406fd14bc51SStefano Zampini 1407fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 14089552c7c7SStefano Zampini PetscInt ii; 14099552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1410ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 14119552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1412ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1413ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1414ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1415ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1416ac47001eSStefano Zampini #else 1417ac47001eSStefano 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); 1418ac47001eSStefano Zampini #endif 14199552c7c7SStefano Zampini } 14209552c7c7SStefano Zampini } 1421fd14bc51SStefano Zampini } 14229162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 14239162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 14249162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 14259162d606SStefano Zampini cum++; 142608122e43SStefano Zampini } 142708122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 142808122e43SStefano Zampini /* shift for next computation */ 142908122e43SStefano Zampini cumarray += subset_size*subset_size; 143008122e43SStefano Zampini } 1431fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1432fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1433fd14bc51SStefano Zampini } 143408122e43SStefano Zampini 143508122e43SStefano Zampini if (mss) { 143608122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 143708122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1438f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1439f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1440f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 144108122e43SStefano Zampini } 1442f6f667cfSStefano Zampini if (allocated_S_St) { 1443f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1444f6f667cfSStefano Zampini } 1445f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 144608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 144708122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 144808122e43SStefano Zampini #endif 144908122e43SStefano Zampini if (pcbddc->dbg_flag) { 14501b968477SStefano Zampini PetscInt maxneigs_r; 1451b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 14529b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 145308122e43SStefano Zampini } 145408122e43SStefano Zampini PetscFunctionReturn(0); 145508122e43SStefano Zampini } 1456b1b3d7a2SStefano Zampini 1457674ae819SStefano Zampini #undef __FUNCT__ 1458c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1459c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1460c8587f34SStefano Zampini { 1461c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 14628629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1463c8587f34SStefano Zampini PetscErrorCode ierr; 1464c8587f34SStefano Zampini 1465c8587f34SStefano Zampini PetscFunctionBegin; 1466f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 14675e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1468c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1469c8587f34SStefano Zampini 1470684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 14710fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1472684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1473c8587f34SStefano Zampini 1474c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1475b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 1476c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 1477c8587f34SStefano Zampini } 1478c8587f34SStefano Zampini 14798629588bSStefano Zampini /* 14808629588bSStefano Zampini Setup local correction and local part of coarse basis. 14818629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 14828629588bSStefano Zampini */ 148347f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 14848629588bSStefano Zampini 14858629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 14868629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 14878629588bSStefano Zampini 14888629588bSStefano Zampini /* free */ 14898629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1490c8587f34SStefano Zampini PetscFunctionReturn(0); 1491c8587f34SStefano Zampini } 1492c8587f34SStefano Zampini 1493c8587f34SStefano Zampini #undef __FUNCT__ 1494674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1495674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1496674ae819SStefano Zampini { 1497674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1498674ae819SStefano Zampini PetscErrorCode ierr; 1499674ae819SStefano Zampini 1500674ae819SStefano Zampini PetscFunctionBegin; 1501674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1502674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 150330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1504674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 1505674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1506785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1507674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1508f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1509f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1510785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 151163602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 151263602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1513674ae819SStefano Zampini PetscFunctionReturn(0); 1514674ae819SStefano Zampini } 1515674ae819SStefano Zampini 1516674ae819SStefano Zampini #undef __FUNCT__ 1517674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1518674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1519674ae819SStefano Zampini { 1520674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15214f1b2e48SStefano Zampini PetscInt i; 1522674ae819SStefano Zampini PetscErrorCode ierr; 1523674ae819SStefano Zampini 1524674ae819SStefano Zampini PetscFunctionBegin; 1525b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1526674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 152716909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 15281dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 1529674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1530674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 15314f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 15324f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 15334f1b2e48SStefano Zampini } 15344f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1535b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1536674ae819SStefano Zampini PetscFunctionReturn(0); 1537674ae819SStefano Zampini } 1538674ae819SStefano Zampini 1539674ae819SStefano Zampini #undef __FUNCT__ 1540674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1541674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1542674ae819SStefano Zampini { 1543674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1544674ae819SStefano Zampini PetscErrorCode ierr; 1545674ae819SStefano Zampini 1546674ae819SStefano Zampini PetscFunctionBegin; 1547674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 154858da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1549ca92afb2SStefano Zampini PetscScalar *array; 155006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 155106656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 155258da7f69SStefano Zampini } 1553674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1554674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 155515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 155615aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1557674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1558674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1559674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 156006656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1561674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1562674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 15638ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1564674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1565674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1566674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1567f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1568f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1569f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1570f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1571727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 15720e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1573f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 157470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 157581d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 15760369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 15771dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 15784f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 15798b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1580ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1581ca92afb2SStefano Zampini PetscInt i; 1582ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1583ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1584ca92afb2SStefano Zampini } 1585ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1586ca92afb2SStefano Zampini } 15874f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1588674ae819SStefano Zampini PetscFunctionReturn(0); 1589674ae819SStefano Zampini } 1590674ae819SStefano Zampini 1591674ae819SStefano Zampini #undef __FUNCT__ 1592f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1593f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 15946bfb1811SStefano Zampini { 15956bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15966bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 15976bfb1811SStefano Zampini VecType impVecType; 15984f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 15996bfb1811SStefano Zampini PetscErrorCode ierr; 16006bfb1811SStefano Zampini 16016bfb1811SStefano Zampini PetscFunctionBegin; 16026c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1603e7b262bdSStefano Zampini /* get sizes */ 16044f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1605b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 16066bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1607e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1608e7b262bdSStefano Zampini /* R nodes */ 1609e7b262bdSStefano Zampini old_size = -1; 1610e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1611e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1612e7b262bdSStefano Zampini } 1613e7b262bdSStefano Zampini if (n_R != old_size) { 1614e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1615e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 16166bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 16176bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 16186bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 16196bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1620e7b262bdSStefano Zampini } 1621e7b262bdSStefano Zampini /* local primal dofs */ 1622e7b262bdSStefano Zampini old_size = -1; 1623e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1624e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1625e7b262bdSStefano Zampini } 1626e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1627e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 162883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1629e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 16306bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1631e7b262bdSStefano Zampini } 1632e7b262bdSStefano Zampini /* local explicit constraints */ 1633e7b262bdSStefano Zampini old_size = -1; 1634e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1635e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1636e7b262bdSStefano Zampini } 1637e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1638e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 163983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 164083b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 164183b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 164283b7ccabSStefano Zampini } 16436bfb1811SStefano Zampini PetscFunctionReturn(0); 16446bfb1811SStefano Zampini } 16456bfb1811SStefano Zampini 16466bfb1811SStefano Zampini #undef __FUNCT__ 164747f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 164847f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 164988ebb749SStefano Zampini { 165025084f0cSStefano Zampini PetscErrorCode ierr; 165125084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 165288ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 165388ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1654d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 165525084f0cSStefano Zampini /* submatrices of local problem */ 165680677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 165706656605SStefano Zampini /* submatrices of local coarse problem */ 165806656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 165925084f0cSStefano Zampini /* working matrices */ 166006656605SStefano Zampini Mat C_CR; 166125084f0cSStefano Zampini /* additional working stuff */ 166206656605SStefano Zampini PC pc_R; 16634f1b2e48SStefano Zampini Mat F; 16645cbda25cSStefano Zampini Vec dummy_vec; 1665a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 166625084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 166706656605SStefano Zampini PetscScalar *work; 166806656605SStefano Zampini PetscInt *idx_V_B; 1669ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 167006656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1671ffd830a3SStefano Zampini 167225084f0cSStefano Zampini /* some shortcuts to scalars */ 167306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 167488ebb749SStefano Zampini 167588ebb749SStefano Zampini PetscFunctionBegin; 1676ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1677ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1678ffd830a3SStefano Zampini } 1679ffd830a3SStefano Zampini 1680ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1681b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 16824f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1683b371cd4fSStefano Zampini n_B = pcis->n_B; 1684b371cd4fSStefano Zampini n_D = pcis->n - n_B; 168588ebb749SStefano Zampini n_R = pcis->n - n_vertices; 168688ebb749SStefano Zampini 168788ebb749SStefano Zampini /* vertices in boundary numbering */ 1688785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 16890e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 16906c4ed002SBarry 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); 169188ebb749SStefano Zampini 169206656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1693019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 169406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 169506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 169606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 169706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 169806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 169906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 170006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 170106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 170206656605SStefano Zampini 170306656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 170406656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 170506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 170606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 170706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1708ffd830a3SStefano Zampini lda_rhs = n_R; 1709a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 171006656605SStefano Zampini if (isLU || isILU || isCHOL) { 171106656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1712df4d28bfSStefano Zampini } else if (sub_schurs->reuse_solver) { 1713df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1714d62866d3SStefano Zampini MatFactorType type; 1715d62866d3SStefano Zampini 1716df4d28bfSStefano Zampini F = reuse_solver->F; 17176816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1718d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1719ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 172022db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 172106656605SStefano Zampini } else { 172206656605SStefano Zampini F = NULL; 172306656605SStefano Zampini } 172406656605SStefano Zampini 1725ffd830a3SStefano Zampini /* allocate workspace */ 1726ffd830a3SStefano Zampini n = 0; 1727ffd830a3SStefano Zampini if (n_constraints) { 1728ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1729ffd830a3SStefano Zampini } 1730ffd830a3SStefano Zampini if (n_vertices) { 1731ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1732ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1733ffd830a3SStefano Zampini } 1734ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1735ffd830a3SStefano Zampini 17365cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 17375cbda25cSStefano Zampini dummy_vec = NULL; 17385cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 17395cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 17405cbda25cSStefano Zampini } 17415cbda25cSStefano Zampini 174288ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 174388ebb749SStefano Zampini if (n_constraints) { 174472b8c272SStefano Zampini Mat M1,M2,M3,C_B; 174506656605SStefano Zampini IS is_aux; 174680677318SStefano Zampini PetscScalar *array,*array2; 174706656605SStefano Zampini 1748f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 174980677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 175088ebb749SStefano Zampini 175125084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 175225084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 17538ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 175472b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 175588ebb749SStefano Zampini 175680677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 175780677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1758ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 175988ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 176006656605SStefano Zampini const PetscScalar *row_cmat_values; 176106656605SStefano Zampini const PetscInt *row_cmat_indices; 176206656605SStefano Zampini PetscInt size_of_constraint,j; 176388ebb749SStefano Zampini 176406656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 176506656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1766ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 176706656605SStefano Zampini } 176806656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 176906656605SStefano Zampini } 1770ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 177106656605SStefano Zampini if (F) { 177206656605SStefano Zampini Mat B; 177306656605SStefano Zampini 1774ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1775a3df083aSStefano Zampini if (need_benign_correction) { 1776df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1777a3df083aSStefano Zampini 177872b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 177972b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 1780a3df083aSStefano Zampini } 178180677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1782a3df083aSStefano Zampini if (need_benign_correction) { 1783a3df083aSStefano Zampini PetscScalar *marr; 1784df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1785a3df083aSStefano Zampini 1786a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 17875cbda25cSStefano Zampini if (lda_rhs != n_R) { 17885cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 17895cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 17905cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 17915cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 17925cbda25cSStefano Zampini } 17935cbda25cSStefano Zampini } else { 1794a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1795a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 17965cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 1797a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1798a3df083aSStefano Zampini } 17995cbda25cSStefano Zampini } 1800a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1801a3df083aSStefano Zampini } 180206656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 180306656605SStefano Zampini } else { 180480677318SStefano Zampini PetscScalar *marr; 180580677318SStefano Zampini 180680677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 180706656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1808ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1809ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 181006656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 181106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 181206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 181306656605SStefano Zampini } 181480677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 181506656605SStefano Zampini } 181680677318SStefano Zampini if (!pcbddc->switch_static) { 181780677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 181880677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 181980677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 182080677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1821ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 182280677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 182380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 182480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 182580677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 182680677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 182780677318SStefano Zampini } 182880677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 182980677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 183072b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 183180677318SStefano Zampini } else { 1832ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1833ffd830a3SStefano Zampini IS dummy; 1834ffd830a3SStefano Zampini 1835ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 183672b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1837ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1838ffd830a3SStefano Zampini } else { 183980677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 184080677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1841ffd830a3SStefano Zampini } 184225084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 184380677318SStefano Zampini } 184480677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 184580677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 184680677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 184706656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 184806656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 184980677318SStefano Zampini if (isCHOL) { 185080677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 185180677318SStefano Zampini } else { 185225084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 185380677318SStefano Zampini } 185480677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 185506656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 185625084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 185725084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 185825084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 185980677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 186072b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 186172b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 186206656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 186306656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1864f4ddd8eeSStefano Zampini } 1865fc227af8SStefano Zampini 1866fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 186788ebb749SStefano Zampini if (n_vertices) { 186806656605SStefano Zampini IS is_aux; 18693a50541eSStefano Zampini 1870df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 18716816873aSStefano Zampini IS tis; 18726816873aSStefano Zampini 18736816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 18746816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 18756816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 18766816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 18776816873aSStefano Zampini } else { 18783a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 18796816873aSStefano Zampini } 18809577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 18819577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 188204708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 188325084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 188488ebb749SStefano Zampini } 188588ebb749SStefano Zampini 188688ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1887f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 188806656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 188906656605SStefano Zampini if (pcbddc->coarse_phi_D) { 189006656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 189106656605SStefano Zampini } 1892f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 189306656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 189406656605SStefano Zampini PetscScalar *marray; 189506656605SStefano Zampini 189606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 189706656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1898f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1899f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1900f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1901f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1902f4ddd8eeSStefano Zampini } 1903f4ddd8eeSStefano Zampini } 190406656605SStefano Zampini 1905f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 190606656605SStefano Zampini PetscScalar *marray; 190788ebb749SStefano Zampini 190806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 19098eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 191006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 191188ebb749SStefano Zampini } 19123301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 191306656605SStefano Zampini n *= 2; 191488ebb749SStefano Zampini } 191506656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 191606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 191706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 19188eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 191906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 192006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 192188ebb749SStefano Zampini } 19223301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 192306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 19248eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 192506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 192606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 192788ebb749SStefano Zampini } 192888ebb749SStefano Zampini } else { 1929c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1930c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 19311b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1932c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1933c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1934c0553b1fSStefano Zampini } 193588ebb749SStefano Zampini } 193606656605SStefano Zampini } 1937019a44ceSStefano Zampini 193806656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 19394f1b2e48SStefano Zampini p0_lidx_I = NULL; 19404f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1941d12edf2fSStefano Zampini const PetscInt *idxs; 1942d12edf2fSStefano Zampini 1943d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 19444f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 19454f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 19464f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 19474f1b2e48SStefano Zampini } 1948d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1949d12edf2fSStefano Zampini } 1950d16cbb6bSStefano Zampini 195106656605SStefano Zampini /* vertices */ 195206656605SStefano Zampini if (n_vertices) { 195316f15bc4SStefano Zampini 1954af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 195504708bb6SStefano Zampini 195616f15bc4SStefano Zampini if (n_R) { 195714393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 195806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 195916f15bc4SStefano Zampini PetscScalar *x,*y; 196004708bb6SStefano Zampini PetscBool isseqaij; 196106656605SStefano Zampini 196221eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 196314393ed6SStefano Zampini if (need_benign_correction) { 196414393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 196514393ed6SStefano Zampini IS is_p0; 196614393ed6SStefano Zampini PetscInt *idxs_p0,n; 196714393ed6SStefano Zampini 196814393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 196914393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 197014393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 1971af25d912SStefano 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); 197214393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 197314393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 197414393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 197514393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 197614393ed6SStefano Zampini } 197714393ed6SStefano Zampini 1978ffd830a3SStefano Zampini if (lda_rhs == n_R) { 1979af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 1980ffd830a3SStefano Zampini } else { 1981ca92afb2SStefano Zampini PetscScalar *av,*array; 1982ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 1983ca92afb2SStefano Zampini PetscInt n; 1984ca92afb2SStefano Zampini PetscBool flg_row; 1985ffd830a3SStefano Zampini 1986ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 1987ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 19889d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 1989ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1990ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 1991ca92afb2SStefano Zampini for (i=0;i<n;i++) { 1992ca92afb2SStefano Zampini PetscInt j; 1993ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 1994ffd830a3SStefano Zampini } 1995ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1996ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1997ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 1998ffd830a3SStefano Zampini } 1999ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2000a3df083aSStefano Zampini if (need_benign_correction) { 2001df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2002a3df083aSStefano Zampini PetscScalar *marr; 2003a3df083aSStefano Zampini 2004a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 200514393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 200614393ed6SStefano Zampini 200714393ed6SStefano Zampini | 0 0 0 | (V) 200814393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 200914393ed6SStefano Zampini | 0 0 -1 | (p0) 201014393ed6SStefano Zampini 201114393ed6SStefano Zampini */ 2012df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 201314393ed6SStefano Zampini const PetscScalar *vals; 201414393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 201514393ed6SStefano Zampini PetscInt n,j,nz; 201614393ed6SStefano Zampini 2017df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2018df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 201914393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 202014393ed6SStefano Zampini for (j=0;j<n;j++) { 202114393ed6SStefano Zampini PetscScalar val = vals[j]; 202214393ed6SStefano Zampini PetscInt k,col = idxs[j]; 202314393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 202414393ed6SStefano Zampini } 202514393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2026df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 202714393ed6SStefano Zampini } 202872b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 202972b8c272SStefano Zampini } 203072b8c272SStefano Zampini if (F) { 203114393ed6SStefano Zampini /* need to correct the rhs */ 203272b8c272SStefano Zampini if (need_benign_correction) { 203372b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 203472b8c272SStefano Zampini PetscScalar *marr; 203572b8c272SStefano Zampini 203672b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 20375cbda25cSStefano Zampini if (lda_rhs != n_R) { 20385cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 20395cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 20405cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 20415cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 20425cbda25cSStefano Zampini } 20435cbda25cSStefano Zampini } else { 2044a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2045a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 20465cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2047a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2048a3df083aSStefano Zampini } 20495cbda25cSStefano Zampini } 2050a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 2051a3df083aSStefano Zampini } 205206656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 205314393ed6SStefano Zampini /* need to correct the solution */ 2054a3df083aSStefano Zampini if (need_benign_correction) { 2055df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2056a3df083aSStefano Zampini PetscScalar *marr; 2057a3df083aSStefano Zampini 2058a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 20595cbda25cSStefano Zampini if (lda_rhs != n_R) { 20605cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 20615cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 20625cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 20635cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 20645cbda25cSStefano Zampini } 20655cbda25cSStefano Zampini } else { 2066a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2067a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 20685cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2069a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2070a3df083aSStefano Zampini } 20715cbda25cSStefano Zampini } 2072a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 2073a3df083aSStefano Zampini } 207406656605SStefano Zampini } else { 207506656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 207606656605SStefano Zampini for (i=0;i<n_vertices;i++) { 2077ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 2078ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 207906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 208006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 208106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 208206656605SStefano Zampini } 208306656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 208406656605SStefano Zampini } 208580677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2086ffd830a3SStefano Zampini /* S_VV and S_CV */ 208706656605SStefano Zampini if (n_constraints) { 208806656605SStefano Zampini Mat B; 208980677318SStefano Zampini 2090ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 209180677318SStefano Zampini for (i=0;i<n_vertices;i++) { 2092ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 2093ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 209480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 209580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 209680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 209780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 209880677318SStefano Zampini } 2099ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 210080677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 210180677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 2102ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 210380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 210406656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 2105ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 2106ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 210706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 210806656605SStefano Zampini } 210904708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 211004708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 2111511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 211204708bb6SStefano Zampini } 2113ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2114ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 2115ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2116ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 2117ffd830a3SStefano Zampini } 211806656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 211914393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 212014393ed6SStefano Zampini if (need_benign_correction) { 2121df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 212214393ed6SStefano Zampini PetscScalar *marr,*sums; 212314393ed6SStefano Zampini 212414393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 212514393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 2126df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 212714393ed6SStefano Zampini const PetscScalar *vals; 212814393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 212914393ed6SStefano Zampini PetscInt n,j,nz; 213014393ed6SStefano Zampini 2131df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2132df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 213314393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 213414393ed6SStefano Zampini PetscInt k; 213514393ed6SStefano Zampini sums[j] = 0.; 213614393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 213714393ed6SStefano Zampini } 213814393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 213914393ed6SStefano Zampini for (j=0;j<n;j++) { 214014393ed6SStefano Zampini PetscScalar val = vals[j]; 214114393ed6SStefano Zampini PetscInt k; 214214393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 214314393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 214414393ed6SStefano Zampini } 214514393ed6SStefano Zampini } 214614393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2147df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 214814393ed6SStefano Zampini } 214914393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 215014393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 215114393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 215214393ed6SStefano Zampini } 215380677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 215406656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 215506656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 215606656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 215706656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 215806656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 215906656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 216006656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2161d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 2162019a44ceSStefano Zampini } else { 2163d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2164d16cbb6bSStefano Zampini } 216521eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 2166d16cbb6bSStefano Zampini 216706656605SStefano Zampini /* coarse basis functions */ 216806656605SStefano Zampini for (i=0;i<n_vertices;i++) { 216916f15bc4SStefano Zampini PetscScalar *y; 217016f15bc4SStefano Zampini 2171ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 217206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 217306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 217406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 217506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 217606656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 217706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 217806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 217906656605SStefano Zampini 218006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 21814f1b2e48SStefano Zampini PetscInt j; 21824f1b2e48SStefano Zampini 218306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 218406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 218506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 21884f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 218906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 219006656605SStefano Zampini } 219106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 219206656605SStefano Zampini } 219304708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 219404708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 219506656605SStefano Zampini } 21965cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 219706656605SStefano Zampini 219806656605SStefano Zampini if (n_constraints) { 219906656605SStefano Zampini Mat B; 220006656605SStefano Zampini 2201ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 220206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 220380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 220406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 220506656605SStefano Zampini if (n_vertices) { 220680677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 220780677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 220880677318SStefano Zampini } else { 220980677318SStefano Zampini Mat S_VCt; 221080677318SStefano Zampini 2211ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2212ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 221372b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 2214ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 2215ffd830a3SStefano Zampini } 221680677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 221780677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 221880677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 221980677318SStefano Zampini } 222006656605SStefano Zampini } 222106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 222206656605SStefano Zampini /* coarse basis functions */ 222306656605SStefano Zampini for (i=0;i<n_constraints;i++) { 222406656605SStefano Zampini PetscScalar *y; 222506656605SStefano Zampini 2226ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 222706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 222806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 222906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 223006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 223106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 223206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 223306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 22344f1b2e48SStefano Zampini PetscInt j; 22354f1b2e48SStefano Zampini 223606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 223706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 223806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 223906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 224006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 22414f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 224206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 224306656605SStefano Zampini } 224406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 224506656605SStefano Zampini } 224606656605SStefano Zampini } 224780677318SStefano Zampini if (n_constraints) { 224880677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 224980677318SStefano Zampini } 22504f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 225172b8c272SStefano Zampini 225272b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 225372b8c272SStefano Zampini if (pcbddc->benign_n) { 225472b8c272SStefano Zampini Mat B0_B,B0_BPHI; 225572b8c272SStefano Zampini IS is_dummy; 225672b8c272SStefano Zampini PetscScalar *data; 225772b8c272SStefano Zampini PetscInt j; 225872b8c272SStefano Zampini 225972b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 226072b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 226172b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 226272b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 226386c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 226472b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 226572b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 226672b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 226772b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 226872b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 226972b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 227072b8c272SStefano Zampini } 227172b8c272SStefano Zampini } 227272b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 227372b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 227472b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 227572b8c272SStefano Zampini } 2276019a44ceSStefano Zampini 227706656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 22783301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 2279ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 2280ffd830a3SStefano Zampini PetscScalar *marray; 228106656605SStefano Zampini 228206656605SStefano Zampini if (n_constraints) { 2283ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 228406656605SStefano Zampini 2285af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 228606656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 2287ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 228816f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 228906656605SStefano Zampini if (n_vertices) { 2290ffd830a3SStefano Zampini Mat S_VCT; 229106656605SStefano Zampini 229206656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 2293ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 229416f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 229506656605SStefano Zampini } 2296ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 229706656605SStefano Zampini } 229816f15bc4SStefano Zampini if (n_vertices && n_R) { 2299ffd830a3SStefano Zampini PetscScalar *av,*marray; 2300ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 2301ffd830a3SStefano Zampini PetscInt n; 2302ffd830a3SStefano Zampini PetscBool flg_row; 230306656605SStefano Zampini 2304ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 2305af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 2306ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2307ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 2308ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2309ffd830a3SStefano Zampini for (i=0;i<n;i++) { 2310ffd830a3SStefano Zampini PetscInt j; 2311ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 2312ffd830a3SStefano Zampini } 2313ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2314ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2315ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 231606656605SStefano Zampini } 231706656605SStefano Zampini 2318ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 2319ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2320ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 2321ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 2322ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 232306656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 232406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 232506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 232606656605SStefano Zampini } 2327ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2328ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 2329ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 2330ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 2331ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 2332ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2333ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2334ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 233506656605SStefano Zampini } 2336ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 233706656605SStefano Zampini /* coarse basis functions */ 233806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 233906656605SStefano Zampini PetscScalar *y; 234006656605SStefano Zampini 2341ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 234206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 234306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 234406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 234506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 234606656605SStefano Zampini if (i<n_vertices) { 234706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 234806656605SStefano Zampini } 234906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 235006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 235106656605SStefano Zampini 235206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 235306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 235406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 235506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 235606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 235706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 235806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 235906656605SStefano Zampini } 236006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 236106656605SStefano Zampini } 2362ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2363ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 236406656605SStefano Zampini } 2365d62866d3SStefano Zampini /* free memory */ 236688ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 236706656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 236806656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 236906656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 237006656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2371d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2372d62866d3SStefano Zampini if (n_vertices) { 2373d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2374d62866d3SStefano Zampini } 2375d62866d3SStefano Zampini if (n_constraints) { 2376d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2377d62866d3SStefano Zampini } 237888ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 237988ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 238088ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2381d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 238288ebb749SStefano Zampini Mat coarse_sub_mat; 238325084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 238488ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 238588ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 238688ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 23878bec7fa6SStefano Zampini Mat C_B,CPHI; 23888bec7fa6SStefano Zampini IS is_dummy; 23898bec7fa6SStefano Zampini Vec mones; 239088ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 239188ebb749SStefano Zampini PetscReal real_value; 239288ebb749SStefano Zampini 2393a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2394a3df083aSStefano Zampini Mat A; 2395a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2396a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2397a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2398a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2399a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2400a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2401a3df083aSStefano Zampini } else { 240288ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 240388ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 240488ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 240588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2406a3df083aSStefano Zampini } 240788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 240888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2409ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 241088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 241188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 241288ebb749SStefano Zampini } 241388ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 241488ebb749SStefano Zampini 241525084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 24163301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 241725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2418ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 241988ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 242088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 242188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 242288ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 242388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 242488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 242588ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 242688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 242788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 242888ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 242988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 243088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 243188ebb749SStefano Zampini } else { 243288ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 243388ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 243488ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 243588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 243688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 243788ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 243888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 243988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 244088ebb749SStefano Zampini } 244188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 244288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 244388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2444511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 24454f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2446fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 2447d12edf2fSStefano Zampini PetscScalar *data,*data2; 24484f1b2e48SStefano Zampini PetscInt j; 2449d12edf2fSStefano Zampini 24504f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2451fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 2452d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 245386c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2454d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2455d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 24564f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 24574f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2458d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 24594f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 24604f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 24614f1b2e48SStefano Zampini } 2462d12edf2fSStefano Zampini } 2463d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2464d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2465d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2466d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2467d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2468d12edf2fSStefano Zampini } 2469d12edf2fSStefano Zampini #if 0 2470d12edf2fSStefano Zampini { 2471d12edf2fSStefano Zampini PetscViewer viewer; 2472d12edf2fSStefano Zampini char filename[256]; 2473ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2474d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2475d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2476ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2477ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2478ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2479d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 248072b8c272SStefano Zampini if (save_change) { 248172b8c272SStefano Zampini Mat phi_B; 248272b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 248372b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 248472b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 248572b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 248672b8c272SStefano Zampini } else { 2487ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2488ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 248972b8c272SStefano Zampini } 2490ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2491ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2492ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2493ffd830a3SStefano Zampini } 2494ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2495ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2496ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2497ffd830a3SStefano Zampini } 249872b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 2499ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2500ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2501ffd830a3SStefano Zampini } 2502d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2503d12edf2fSStefano Zampini } 2504d12edf2fSStefano Zampini #endif 250581d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 25068bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 25071575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 250806656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 25098bec7fa6SStefano Zampini 25108bec7fa6SStefano Zampini /* check constraints */ 2511a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2512a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 25134f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 25148bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2515a00504b5SStefano Zampini } else { 2516a00504b5SStefano Zampini PetscScalar *data; 2517a00504b5SStefano Zampini Mat tmat; 2518a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2519a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 2520a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2521a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2522a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2523a00504b5SStefano Zampini } 25248bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 25258bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 25268bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 25278bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2528bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2529ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2530bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2531bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2532bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2533bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2534bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 253588ebb749SStefano Zampini } 25368bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 25378bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 25388bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 25398bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 254025084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 254188ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 254288ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 254388ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 254488ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 254588ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 254688ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 254788ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 254888ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 254988ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 255088ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2551ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 255288ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 255388ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 255488ebb749SStefano Zampini } 255588ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 255688ebb749SStefano Zampini } 25578629588bSStefano Zampini /* get back data */ 25588629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 255988ebb749SStefano Zampini PetscFunctionReturn(0); 256088ebb749SStefano Zampini } 256188ebb749SStefano Zampini 256288ebb749SStefano Zampini #undef __FUNCT__ 2563d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2564d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2565aa0d41d4SStefano Zampini { 2566d65f70fdSStefano Zampini Mat *work_mat; 2567d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2568d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2569d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 2570aa0d41d4SStefano Zampini PetscErrorCode ierr; 2571aa0d41d4SStefano Zampini 2572aa0d41d4SStefano Zampini PetscFunctionBegin; 2573d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2574d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2575d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2576d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2577aa0d41d4SStefano Zampini 2578d65f70fdSStefano Zampini if (!rsorted) { 2579906d46d4SStefano Zampini const PetscInt *idxs; 2580906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2581aa0d41d4SStefano Zampini 2582d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2583d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2584d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2585d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2586aa0d41d4SStefano Zampini } 2587d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2588d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2589d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2590d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2591aa0d41d4SStefano Zampini } 2592d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2593d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2594d65f70fdSStefano Zampini } else { 2595d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2596d65f70fdSStefano Zampini isrow_s = isrow; 2597aa0d41d4SStefano Zampini } 2598906d46d4SStefano Zampini 2599d65f70fdSStefano Zampini if (!csorted) { 2600d65f70fdSStefano Zampini if (isrow == iscol) { 2601d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2602d65f70fdSStefano Zampini iscol_s = isrow_s; 2603d65f70fdSStefano Zampini } else { 2604d65f70fdSStefano Zampini const PetscInt *idxs; 2605d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2606906d46d4SStefano Zampini 2607d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2608d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2609d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2610d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2611d65f70fdSStefano Zampini } 2612d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2613d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2614d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2615d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2616d65f70fdSStefano Zampini } 2617d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2618d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2619d65f70fdSStefano Zampini } 2620d65f70fdSStefano Zampini } else { 2621d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2622d65f70fdSStefano Zampini iscol_s = iscol; 2623d65f70fdSStefano Zampini } 2624d65f70fdSStefano Zampini 2625d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2626d65f70fdSStefano Zampini 2627d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2628906d46d4SStefano Zampini Mat new_mat; 2629d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2630906d46d4SStefano Zampini 2631d65f70fdSStefano Zampini if (!rsorted) { 2632d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2633d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2634d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2635d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2636906d46d4SStefano Zampini } 2637d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2638d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2639d65f70fdSStefano Zampini } else { 2640d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2641906d46d4SStefano Zampini } 2642d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2643d65f70fdSStefano Zampini 2644d65f70fdSStefano Zampini if (!csorted) { 2645d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2646d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2647d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2648d65f70fdSStefano Zampini } else { 2649d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2650d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2651d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2652d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2653d65f70fdSStefano Zampini } 2654d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2655d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2656d65f70fdSStefano Zampini } 2657d65f70fdSStefano Zampini } else { 2658d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2659d65f70fdSStefano Zampini } 2660d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2661d65f70fdSStefano Zampini 2662d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2663d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2664d65f70fdSStefano Zampini work_mat[0] = new_mat; 2665d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2666d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2667d65f70fdSStefano Zampini } 2668d65f70fdSStefano Zampini 2669d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2670d65f70fdSStefano Zampini *B = work_mat[0]; 2671d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2672d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2673d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2674d65f70fdSStefano Zampini PetscFunctionReturn(0); 2675d65f70fdSStefano Zampini } 2676d65f70fdSStefano Zampini 2677d65f70fdSStefano Zampini #undef __FUNCT__ 26785e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 26795e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2680aa0d41d4SStefano Zampini { 2681aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 26825e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2683d65f70fdSStefano Zampini Mat new_mat; 26845e8657edSStefano Zampini IS is_local,is_global; 2685d65f70fdSStefano Zampini PetscInt local_size; 2686d65f70fdSStefano Zampini PetscBool isseqaij; 2687aa0d41d4SStefano Zampini PetscErrorCode ierr; 2688aa0d41d4SStefano Zampini 2689aa0d41d4SStefano Zampini PetscFunctionBegin; 2690aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 26915e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 26925e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2693b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2694aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2695d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2696aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2697906d46d4SStefano Zampini 2698906d46d4SStefano Zampini /* check */ 2699906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2700906d46d4SStefano Zampini Vec x,x_change; 2701906d46d4SStefano Zampini PetscReal error; 2702906d46d4SStefano Zampini 27035e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2704906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 27055e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2706e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2707e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2708d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2709e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2710e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2711906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2712906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2713906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2714906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2715906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2716906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2717906d46d4SStefano Zampini } 2718906d46d4SStefano Zampini 271922d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 27209b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 272122d5777bSStefano Zampini if (isseqaij) { 2722a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2723a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 2724aa0d41d4SStefano Zampini } else { 2725a00504b5SStefano Zampini Mat work_mat; 27261cf9b237SStefano Zampini 2727a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2728aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2729a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 2730aa0d41d4SStefano Zampini } 27313301b35fSStefano Zampini if (matis->A->symmetric_set) { 27323301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2733e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 27343301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2735e496cd5dSStefano Zampini #endif 27363301b35fSStefano Zampini } 2737d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2738aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2739aa0d41d4SStefano Zampini } 2740aa0d41d4SStefano Zampini 2741aa0d41d4SStefano Zampini #undef __FUNCT__ 2742a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 27438ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2744a64d13efSStefano Zampini { 2745a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2746a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2747d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 274853892102SStefano Zampini PetscInt *idx_R_local=NULL; 27493a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 27503a50541eSStefano Zampini PetscInt vbs,bs; 27516816873aSStefano Zampini PetscBT bitmask=NULL; 2752a64d13efSStefano Zampini PetscErrorCode ierr; 2753a64d13efSStefano Zampini 2754a64d13efSStefano Zampini PetscFunctionBegin; 2755b23d619eSStefano Zampini /* 2756b23d619eSStefano Zampini No need to setup local scatters if 2757b23d619eSStefano Zampini - primal space is unchanged 2758b23d619eSStefano Zampini AND 2759b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2760b23d619eSStefano Zampini AND 2761b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2762b23d619eSStefano Zampini */ 2763b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2764f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2765f4ddd8eeSStefano Zampini } 2766f4ddd8eeSStefano Zampini /* destroy old objects */ 2767f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2768f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2769f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2770a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2771b371cd4fSStefano Zampini n_B = pcis->n_B; 2772b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2773b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 27743a50541eSStefano Zampini 2775a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 27766816873aSStefano Zampini 277753892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 2778df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2779854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2780a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2781a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 27820e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2783a64d13efSStefano Zampini } 2784a64d13efSStefano Zampini 2785a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 27864641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 27876816873aSStefano Zampini idx_R_local[n_R++] = i; 2788a64d13efSStefano Zampini } 2789a64d13efSStefano Zampini } 2790df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 2791df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 27926816873aSStefano Zampini 2793df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2794df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 27956816873aSStefano Zampini } 27963a50541eSStefano Zampini 27973a50541eSStefano Zampini /* Block code */ 27983a50541eSStefano Zampini vbs = 1; 27993a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 28003a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 28013a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 28023a50541eSStefano Zampini PetscInt *vary; 2803df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2804785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 28053a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2806d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2807d3df7717SStefano 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 */ 28080e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2809d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 28103a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 28113a50541eSStefano Zampini is_blocked = PETSC_FALSE; 28123a50541eSStefano Zampini break; 28133a50541eSStefano Zampini } 28143a50541eSStefano Zampini } 2815d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2816d3df7717SStefano Zampini } else { 2817d3df7717SStefano Zampini /* Verify directly the R set */ 2818d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2819d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2820d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2821d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2822d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2823d3df7717SStefano Zampini break; 2824d3df7717SStefano Zampini } 2825d3df7717SStefano Zampini } 2826d3df7717SStefano Zampini } 2827d3df7717SStefano Zampini } 28283a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 28293a50541eSStefano Zampini vbs = bs; 28303a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 28313a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 28323a50541eSStefano Zampini } 28333a50541eSStefano Zampini } 28343a50541eSStefano Zampini } 28353a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 2836df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2837df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 283853892102SStefano Zampini 2839df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2840df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 284153892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 2842df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 284353892102SStefano Zampini } else { 28443a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 284553892102SStefano Zampini } 2846a64d13efSStefano Zampini 2847a64d13efSStefano Zampini /* print some info if requested */ 2848a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2849a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2850a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 28511575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2852a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2853a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 28544f1b2e48SStefano 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); 2855a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2856a64d13efSStefano Zampini } 2857a64d13efSStefano Zampini 2858a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 2859df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 28606816873aSStefano Zampini IS is_aux1,is_aux2; 28616816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 28626816873aSStefano Zampini 28633a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2864854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2865854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2866a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 28674641a718SStefano Zampini for (i=0; i<n_D; i++) { 28684641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 28694641a718SStefano Zampini } 2870a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2871a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 28724641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 28734641a718SStefano Zampini aux_array1[j++] = i; 2874a64d13efSStefano Zampini } 2875a64d13efSStefano Zampini } 2876a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2877a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2878a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 28794641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 28804641a718SStefano Zampini aux_array2[j++] = i; 2881a64d13efSStefano Zampini } 2882a64d13efSStefano Zampini } 2883a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2884a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2885a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2886a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2887a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2888a64d13efSStefano Zampini 28898eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2890785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2891a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 28924641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 28934641a718SStefano Zampini aux_array1[j++] = i; 2894a64d13efSStefano Zampini } 2895a64d13efSStefano Zampini } 2896a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2897a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2898a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2899a64d13efSStefano Zampini } 29004641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 29013a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2902d62866d3SStefano Zampini } else { 2903df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 29046816873aSStefano Zampini IS tis; 29056816873aSStefano Zampini PetscInt schur_size; 29066816873aSStefano Zampini 2907df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 29086816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 2909df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 29106816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 29116816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 29126816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 29136816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 29146816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2915d62866d3SStefano Zampini } 2916d62866d3SStefano Zampini } 2917a64d13efSStefano Zampini PetscFunctionReturn(0); 2918a64d13efSStefano Zampini } 2919a64d13efSStefano Zampini 2920304d26faSStefano Zampini 2921304d26faSStefano Zampini #undef __FUNCT__ 2922304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2923684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2924304d26faSStefano Zampini { 2925304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2926304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2927304d26faSStefano Zampini PC pc_temp; 2928304d26faSStefano Zampini Mat A_RR; 2929f4ddd8eeSStefano Zampini MatReuse reuse; 2930304d26faSStefano Zampini PetscScalar m_one = -1.0; 2931304d26faSStefano Zampini PetscReal value; 293204708bb6SStefano Zampini PetscInt n_D,n_R; 29339577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2934304d26faSStefano Zampini PetscErrorCode ierr; 2935e604994aSStefano Zampini /* prefixes stuff */ 2936312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2937e604994aSStefano Zampini size_t len; 2938304d26faSStefano Zampini 2939304d26faSStefano Zampini PetscFunctionBegin; 2940304d26faSStefano Zampini 2941e604994aSStefano Zampini /* compute prefixes */ 2942e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2943e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2944e604994aSStefano Zampini if (!pcbddc->current_level) { 2945e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2946e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2947e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2948e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2949e604994aSStefano Zampini } else { 2950e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2951312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2952e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2953e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2954312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2955312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 295634d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 295734d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2958e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2959e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2960e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2961e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2962e604994aSStefano Zampini } 2963e604994aSStefano Zampini 2964304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2965684f6988SStefano Zampini if (dirichlet) { 2966d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2967450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2968450f8f5eSStefano Zampini if (!sub_schurs->reuse_solver) { 2969450f8f5eSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 2970450f8f5eSStefano Zampini } 2971450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 2972a3df083aSStefano Zampini Mat A_IIn; 2973a3df083aSStefano Zampini 2974a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 2975a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 2976a3df083aSStefano Zampini pcis->A_II = A_IIn; 2977a3df083aSStefano Zampini } 2978450f8f5eSStefano Zampini } 29793301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 29803301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2981964fefecSStefano Zampini } 2982ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2983964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2984304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2985304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2986304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2987304d26faSStefano Zampini /* default */ 2988304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2989e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 29909577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2991304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 29929577ea80SStefano Zampini if (issbaij) { 29939577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 29949577ea80SStefano Zampini } else { 2995304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 29969577ea80SStefano Zampini } 2997304d26faSStefano Zampini /* Allow user's customization */ 2998304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2999304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3000304d26faSStefano Zampini } 3001d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 3002df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 3003df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3004d62866d3SStefano Zampini 3005df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 3006d5574798SStefano Zampini } 3007304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3008304d26faSStefano Zampini if (!n_D) { 3009304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 3010304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3011304d26faSStefano Zampini } 3012304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 3013304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 3014304d26faSStefano Zampini /* set ksp_D into pcis data */ 3015304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 3016304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 3017304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 3018684f6988SStefano Zampini } 3019304d26faSStefano Zampini 3020304d26faSStefano Zampini /* NEUMANN PROBLEM */ 3021684f6988SStefano Zampini A_RR = 0; 3022684f6988SStefano Zampini if (neumann) { 3023d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 302404708bb6SStefano Zampini PetscInt ibs,mbs; 302504708bb6SStefano Zampini PetscBool issbaij; 302604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3027f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 30288ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 3029f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 3030f4ddd8eeSStefano Zampini PetscInt nn_R; 303181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 3032f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3033f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 3034f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 3035f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 3036f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3037f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3038f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 3039727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 3040f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3041f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3042f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 3043f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 3044f4ddd8eeSStefano Zampini } 3045f4ddd8eeSStefano Zampini } 3046f4ddd8eeSStefano Zampini /* last check */ 3047d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 3048f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3049f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3050f4ddd8eeSStefano Zampini } 3051f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 3052f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3053f4ddd8eeSStefano Zampini } 3054a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 3055af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 3056af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 305704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 305804708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 305904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 306004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 306104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 3062af732b37SStefano Zampini } else { 3063511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 30646816873aSStefano Zampini } 306504708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 306604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 306704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 306804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 306904708bb6SStefano Zampini } else { 3070511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 307104708bb6SStefano Zampini } 307204708bb6SStefano Zampini } 3073a00504b5SStefano Zampini /* extract A_RR */ 3074a00504b5SStefano Zampini if (sub_schurs->reuse_solver) { 3075a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3076a00504b5SStefano Zampini 3077a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 307816e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3079a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 308016e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 308116e386b8SStefano Zampini } else { 3082a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 3083a00504b5SStefano Zampini } 3084a00504b5SStefano Zampini } else { 3085a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3086a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 3087a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3088a00504b5SStefano Zampini } 3089a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 3090f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 309116e386b8SStefano Zampini } 30923301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 30933301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 30946816873aSStefano Zampini } 3095f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 3096304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 3097304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 3098304d26faSStefano Zampini /* default */ 3099304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 3100e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 3101304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 31029577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 31039577ea80SStefano Zampini if (issbaij) { 31049577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 31059577ea80SStefano Zampini } else { 3106304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 31079577ea80SStefano Zampini } 3108304d26faSStefano Zampini /* Allow user's customization */ 3109304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 3110304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3111304d26faSStefano Zampini } 3112304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3113304d26faSStefano Zampini if (!n_R) { 3114304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 3115304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3116304d26faSStefano Zampini } 31175cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 3118df4d28bfSStefano Zampini /* Reuse solver if it is present */ 3119df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 3120df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3121d62866d3SStefano Zampini 3122df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 3123d62866d3SStefano Zampini } 3124304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 3125304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 3126684f6988SStefano Zampini } 3127304d26faSStefano Zampini 3128304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 31290fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 3130684f6988SStefano Zampini if (pcbddc->dbg_flag) { 3131684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 31321575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3133684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3134684f6988SStefano Zampini } 3135684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 31360fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 31370fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 31380fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 31390fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 31400fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 3141304d26faSStefano Zampini /* need to be adapted? */ 3142b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 3143b2566f29SBarry Smith ierr = MPIU_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3144b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 3145304d26faSStefano Zampini /* print info */ 3146304d26faSStefano Zampini if (pcbddc->dbg_flag) { 3147e604994aSStefano 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); 3148304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3149304d26faSStefano Zampini } 3150b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 3151298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 3152304d26faSStefano Zampini } 3153684f6988SStefano Zampini } 3154684f6988SStefano Zampini if (neumann) { /* Neumann */ 31550fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 31560fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 31570fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 31580fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 31590fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 3160304d26faSStefano Zampini /* need to be adapted? */ 3161b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 3162b2566f29SBarry Smith ierr = MPIU_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3163304d26faSStefano Zampini /* print info */ 3164304d26faSStefano Zampini if (pcbddc->dbg_flag) { 3165e604994aSStefano 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); 3166304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3167304d26faSStefano Zampini } 3168b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 3169298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 3170304d26faSStefano Zampini } 31710fccc4e9SStefano Zampini } 3172684f6988SStefano Zampini } 31735cbda25cSStefano Zampini /* free Neumann problem's matrix */ 31745cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3175304d26faSStefano Zampini PetscFunctionReturn(0); 3176304d26faSStefano Zampini } 3177304d26faSStefano Zampini 3178304d26faSStefano Zampini #undef __FUNCT__ 3179ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 318080677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 3181674ae819SStefano Zampini { 3182674ae819SStefano Zampini PetscErrorCode ierr; 3183674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3184be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3185674ae819SStefano Zampini 3186674ae819SStefano Zampini PetscFunctionBegin; 3187df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 318880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 318920c7b377SStefano Zampini } 319080677318SStefano Zampini if (!pcbddc->switch_static) { 319180677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 319280677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 319380677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 319420c7b377SStefano Zampini } 3195df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 319680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 319780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 319820c7b377SStefano Zampini } else { 3199df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3200be83ff47SStefano Zampini 3201df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3202df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 320320c7b377SStefano Zampini } 3204be83ff47SStefano Zampini } else { 320580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 320680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 320780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 320880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 320980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 321080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 321180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 321280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 321380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3214674ae819SStefano Zampini } 3215674ae819SStefano Zampini } 321672b8c272SStefano Zampini if (!sub_schurs->reuse_solver || pcbddc->switch_static) { 321780677318SStefano Zampini if (applytranspose) { 321880677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 321980677318SStefano Zampini } else { 322080677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 322180677318SStefano Zampini } 3222be83ff47SStefano Zampini } else { 3223df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3224be83ff47SStefano Zampini 3225be83ff47SStefano Zampini if (applytranspose) { 3226df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3227be83ff47SStefano Zampini } else { 3228df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3229be83ff47SStefano Zampini } 3230be83ff47SStefano Zampini } 323180677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 323280677318SStefano Zampini if (!pcbddc->switch_static) { 3233df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 323480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 323580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3236be83ff47SStefano Zampini } else { 3237df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3238be83ff47SStefano Zampini 3239df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3240df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3241be83ff47SStefano Zampini } 324280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 324380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 324480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 324580677318SStefano Zampini } 324680677318SStefano Zampini } else { 324780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 324880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 324980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 325080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 325180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 325280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 325380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 325480677318SStefano Zampini } 325580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 325680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 325780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 325880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3259674ae819SStefano Zampini } 3260674ae819SStefano Zampini PetscFunctionReturn(0); 3261674ae819SStefano Zampini } 3262674ae819SStefano Zampini 3263dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 3264674ae819SStefano Zampini #undef __FUNCT__ 3265674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 3266dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 3267674ae819SStefano Zampini { 3268674ae819SStefano Zampini PetscErrorCode ierr; 3269674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3270674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 3271674ae819SStefano Zampini const PetscScalar zero = 0.0; 3272674ae819SStefano Zampini 3273674ae819SStefano Zampini PetscFunctionBegin; 3274dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 32754fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3276dc359a40SStefano Zampini if (applytranspose) { 3277674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 32788eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 3279dc359a40SStefano Zampini } else { 3280674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 3281674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 328215aaf578SStefano Zampini } 32834fee134fSStefano Zampini } else { 32844fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 32854fee134fSStefano Zampini } 3286efc2fbd9SStefano Zampini 3287efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 32884f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3289efc2fbd9SStefano Zampini PetscScalar *array; 32904f1b2e48SStefano Zampini PetscInt j; 3291efc2fbd9SStefano Zampini 3292efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 32934f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 3294efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3295efc2fbd9SStefano Zampini } 3296efc2fbd9SStefano Zampini 329712edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 329812edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 329912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 330012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 330112edc857SStefano Zampini 33029f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 330312edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 330412edc857SStefano Zampini if (pcbddc->coarse_ksp) { 330551694757SStefano Zampini Mat coarse_mat; 3306964fefecSStefano Zampini Vec rhs,sol; 330751694757SStefano Zampini MatNullSpace nullsp; 330827b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 3309964fefecSStefano Zampini 331027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 331127b6a85dSStefano Zampini PC coarse_pc; 331227b6a85dSStefano Zampini 331327b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 331427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 331527b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 331627b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 331727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 331827b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 33193bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 332027b6a85dSStefano Zampini } 332127b6a85dSStefano Zampini } 3322964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 3323964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 332451694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 332551694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 332651694757SStefano Zampini if (nullsp) { 332751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 332851694757SStefano Zampini } 332912edc857SStefano Zampini if (applytranspose) { 3330*1f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only) { 3331*1f4df5f7SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 33322701bc32SStefano Zampini } else { 3333964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 33342701bc32SStefano Zampini } 33352701bc32SStefano Zampini } else { 3336*1f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 33372701bc32SStefano Zampini PC coarse_pc; 33382701bc32SStefano Zampini 33392701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 33402701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 33412701bc32SStefano Zampini ierr = PCApply(coarse_pc,rhs,sol);CHKERRQ(ierr); 33422701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 334312edc857SStefano Zampini } else { 3344964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 334512edc857SStefano Zampini } 33462701bc32SStefano Zampini } 334727b6a85dSStefano Zampini /* we don't the benign correction at coarser levels anymore */ 334827b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 334927b6a85dSStefano Zampini PC coarse_pc; 335027b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 335127b6a85dSStefano Zampini 335227b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 335327b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 335427b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 33553bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 335627b6a85dSStefano Zampini } 335751694757SStefano Zampini if (nullsp) { 335851694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 335951694757SStefano Zampini } 336012edc857SStefano Zampini } 3361674ae819SStefano Zampini 3362674ae819SStefano Zampini /* Local solution on R nodes */ 33634fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 336480677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 33659f00e9b4SStefano Zampini } 33669f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 33679f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 336812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3369674ae819SStefano Zampini 33704fee134fSStefano Zampini /* Sum contributions from the two levels */ 33714fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3372dc359a40SStefano Zampini if (applytranspose) { 3373dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3374dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3375dc359a40SStefano Zampini } else { 3376674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 33778eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3378dc359a40SStefano Zampini } 3379efc2fbd9SStefano Zampini /* store p0 */ 33804f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3381efc2fbd9SStefano Zampini PetscScalar *array; 33824f1b2e48SStefano Zampini PetscInt j; 3383efc2fbd9SStefano Zampini 3384efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 33854f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 3386efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3387efc2fbd9SStefano Zampini } 33884fee134fSStefano Zampini } else { /* expand the coarse solution */ 33894fee134fSStefano Zampini if (applytranspose) { 33904fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 33914fee134fSStefano Zampini } else { 33924fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 33934fee134fSStefano Zampini } 33944fee134fSStefano Zampini } 3395674ae819SStefano Zampini PetscFunctionReturn(0); 3396674ae819SStefano Zampini } 3397674ae819SStefano Zampini 3398674ae819SStefano Zampini #undef __FUNCT__ 3399674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 340012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 3401674ae819SStefano Zampini { 3402674ae819SStefano Zampini PetscErrorCode ierr; 3403674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 340458da7f69SStefano Zampini PetscScalar *array; 340512edc857SStefano Zampini Vec from,to; 3406674ae819SStefano Zampini 3407674ae819SStefano Zampini PetscFunctionBegin; 340812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 340912edc857SStefano Zampini from = pcbddc->coarse_vec; 341012edc857SStefano Zampini to = pcbddc->vec1_P; 341112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 341212edc857SStefano Zampini Vec tvec; 341358da7f69SStefano Zampini 341458da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 341558da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 341612edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 341758da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 341858da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 341958da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 342012edc857SStefano Zampini } 342112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 342212edc857SStefano Zampini from = pcbddc->vec1_P; 342312edc857SStefano Zampini to = pcbddc->coarse_vec; 342412edc857SStefano Zampini } 342512edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3426674ae819SStefano Zampini PetscFunctionReturn(0); 3427674ae819SStefano Zampini } 3428674ae819SStefano Zampini 3429674ae819SStefano Zampini #undef __FUNCT__ 3430674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 343112edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3432674ae819SStefano Zampini { 3433674ae819SStefano Zampini PetscErrorCode ierr; 3434674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 343558da7f69SStefano Zampini PetscScalar *array; 343612edc857SStefano Zampini Vec from,to; 3437674ae819SStefano Zampini 3438674ae819SStefano Zampini PetscFunctionBegin; 343912edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 344012edc857SStefano Zampini from = pcbddc->coarse_vec; 344112edc857SStefano Zampini to = pcbddc->vec1_P; 344212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 344312edc857SStefano Zampini from = pcbddc->vec1_P; 344412edc857SStefano Zampini to = pcbddc->coarse_vec; 344512edc857SStefano Zampini } 344612edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 344712edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 344812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 344912edc857SStefano Zampini Vec tvec; 345058da7f69SStefano Zampini 345112edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 345258da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 345358da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 345458da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 345558da7f69SStefano Zampini } 345658da7f69SStefano Zampini } else { 345758da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 345858da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 345912edc857SStefano Zampini } 346012edc857SStefano Zampini } 3461674ae819SStefano Zampini PetscFunctionReturn(0); 3462674ae819SStefano Zampini } 3463674ae819SStefano Zampini 3464984c4197SStefano Zampini /* uncomment for testing purposes */ 3465984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3466674ae819SStefano Zampini #undef __FUNCT__ 3467674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3468674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3469674ae819SStefano Zampini { 3470674ae819SStefano Zampini PetscErrorCode ierr; 3471674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3472674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3473674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3474984c4197SStefano Zampini /* one and zero */ 3475984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3476984c4197SStefano Zampini /* space to store constraints and their local indices */ 34779162d606SStefano Zampini PetscScalar *constraints_data; 34789162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 34799162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 34809162d606SStefano Zampini PetscInt *constraints_n; 3481984c4197SStefano Zampini /* iterators */ 3482b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3483984c4197SStefano Zampini /* BLAS integers */ 3484e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3485e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3486c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3487727cdba6SStefano Zampini /* reuse */ 34880e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 34890e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3490984c4197SStefano Zampini /* change of basis */ 3491b3d85658SStefano Zampini PetscBool qr_needed; 34929162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3493984c4197SStefano Zampini /* auxiliary stuff */ 349464efe560SStefano Zampini PetscInt *nnz,*is_indices; 34958a0068c3SStefano Zampini PetscInt ncc; 3496984c4197SStefano Zampini /* some quantities */ 349745a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3498a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3499984c4197SStefano Zampini 3500674ae819SStefano Zampini PetscFunctionBegin; 35018e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 35028e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 35038e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 350416909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 3505088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3506088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 35070e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 35080e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 35090e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 35100e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 35110e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3512088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3513cf5a6209SStefano Zampini 3514cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 35159162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3516cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3517cf5a6209SStefano Zampini const Vec *nearnullvecs; 3518cf5a6209SStefano Zampini Vec *localnearnullsp; 3519cf5a6209SStefano Zampini PetscScalar *array; 3520cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3521cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3522674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3523b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3524674ae819SStefano Zampini PetscScalar *work; 3525674ae819SStefano Zampini PetscReal *singular_vals; 3526674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3527674ae819SStefano Zampini PetscReal *rwork; 3528674ae819SStefano Zampini #endif 3529674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3530674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3531674ae819SStefano Zampini #else 3532964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3533964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3534674ae819SStefano Zampini #endif 3535674ae819SStefano Zampini 3536674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3537d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3538e4d548c7SStefano Zampini /* print some info */ 3539*1f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 3540e4d548c7SStefano Zampini PetscInt nv; 3541e4d548c7SStefano Zampini 3542e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 3543e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 3544e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3545e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3546e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3547e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 3548e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 3549e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3550e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3551e4d548c7SStefano Zampini } 3552e4d548c7SStefano Zampini 3553d06fc5fdSStefano Zampini /* free unneeded index sets */ 3554d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3555d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3556674ae819SStefano Zampini } 3557d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3558d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3559d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3560d06fc5fdSStefano Zampini } 3561d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3562d06fc5fdSStefano Zampini n_ISForEdges = 0; 3563d06fc5fdSStefano Zampini } 3564d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3565d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3566d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3567d06fc5fdSStefano Zampini } 3568d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3569d06fc5fdSStefano Zampini n_ISForFaces = 0; 3570d06fc5fdSStefano Zampini } 357170022509SStefano Zampini 357270022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 357370022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 357470022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 357570022509SStefano Zampini if (pcbddc->NullSpace) { 357670022509SStefano Zampini PetscBool tbool[2],gbool[2]; 357770022509SStefano Zampini 357870022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 3579b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 3580d06fc5fdSStefano Zampini if (!ISForEdges) { 3581d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 3582d06fc5fdSStefano Zampini } 3583b8ffe317SStefano Zampini } 3584d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 3585d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 3586b2566f29SBarry Smith ierr = MPIU_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3587d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 3588d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 358998a51de6SStefano Zampini } 359070022509SStefano Zampini #endif 359108122e43SStefano Zampini 3592674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3593674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3594674ae819SStefano Zampini if (nearnullsp) { 3595674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3596f4ddd8eeSStefano Zampini /* remove any stored info */ 3597f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3598f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3599f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3600f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3601f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3602473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3603f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3604f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3605f4ddd8eeSStefano Zampini } 3606984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3607984c4197SStefano Zampini nnsp_size = 0; 3608674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3609674ae819SStefano Zampini } 3610984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3611984c4197SStefano Zampini max_constraints = nnsp_size; 3612984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3613984c4197SStefano Zampini 3614674ae819SStefano Zampini /* 3615674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 36169162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 36179162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 36189162d606SStefano Zampini There can be multiple constraints per connected component 3619674ae819SStefano Zampini */ 3620674ae819SStefano Zampini n_vertices = 0; 3621674ae819SStefano Zampini if (ISForVertices) { 3622674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3623674ae819SStefano Zampini } 36249162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 36259162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 36269162d606SStefano Zampini 36279162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 36289162d606SStefano Zampini total_counts *= max_constraints; 3629674ae819SStefano Zampini total_counts += n_vertices; 36304641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 36319162d606SStefano Zampini 3632674ae819SStefano Zampini total_counts = 0; 3633674ae819SStefano Zampini max_size_of_constraint = 0; 3634674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 36359162d606SStefano Zampini IS used_is; 3636674ae819SStefano Zampini if (i<n_ISForEdges) { 36379162d606SStefano Zampini used_is = ISForEdges[i]; 3638674ae819SStefano Zampini } else { 36399162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3640674ae819SStefano Zampini } 36419162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3642674ae819SStefano Zampini total_counts += j; 3643674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3644674ae819SStefano Zampini } 36459162d606SStefano 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); 36469162d606SStefano Zampini 3647984c4197SStefano Zampini /* get local part of global near null space vectors */ 3648785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3649984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3650984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3651e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3652e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3653984c4197SStefano Zampini } 3654674ae819SStefano Zampini 3655242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3656242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3657a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3658242a89d7SStefano Zampini 3659984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3660a773dcb8SStefano Zampini if (!skip_lapack) { 3661674ae819SStefano Zampini PetscScalar temp_work; 3662911cabfeSStefano Zampini 3663674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3664984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3665785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3666785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3667785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3668674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3669785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3670674ae819SStefano Zampini #endif 3671674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3672c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3673c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3674674ae819SStefano Zampini lwork = -1; 3675674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3676674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3677c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3678674ae819SStefano Zampini #else 3679c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3680674ae819SStefano Zampini #endif 3681674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3682984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3683674ae819SStefano Zampini #else /* on missing GESVD */ 3684674ae819SStefano Zampini /* SVD */ 3685674ae819SStefano Zampini PetscInt max_n,min_n; 3686674ae819SStefano Zampini max_n = max_size_of_constraint; 3687984c4197SStefano Zampini min_n = max_constraints; 3688984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3689674ae819SStefano Zampini min_n = max_size_of_constraint; 3690984c4197SStefano Zampini max_n = max_constraints; 3691674ae819SStefano Zampini } 3692785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3693674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3694785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3695674ae819SStefano Zampini #endif 3696674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3697674ae819SStefano Zampini lwork = -1; 3698e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3699e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3700b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3701674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3702674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 37039162d606SStefano 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)); 3704674ae819SStefano Zampini #else 37059162d606SStefano 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)); 3706674ae819SStefano Zampini #endif 3707674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3708984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3709984c4197SStefano Zampini #endif /* on missing GESVD */ 3710674ae819SStefano Zampini /* Allocate optimal workspace */ 3711674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3712854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3713674ae819SStefano Zampini } 3714674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3715674ae819SStefano Zampini total_counts = 0; 37169162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 37179162d606SStefano Zampini constraints_data_ptr[0] = 0; 3718674ae819SStefano Zampini /* vertices */ 37199162d606SStefano Zampini if (n_vertices) { 3720674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 37219162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3722674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 37239162d606SStefano Zampini constraints_n[total_counts] = 1; 37249162d606SStefano Zampini constraints_data[total_counts] = 1.0; 37259162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 37269162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3727674ae819SStefano Zampini total_counts++; 3728674ae819SStefano Zampini } 3729674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3730674ae819SStefano Zampini n_vertices = total_counts; 3731674ae819SStefano Zampini } 3732984c4197SStefano Zampini 3733674ae819SStefano Zampini /* edges and faces */ 37349162d606SStefano Zampini total_counts_cc = total_counts; 3735911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 37369162d606SStefano Zampini IS used_is; 37379162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 37389162d606SStefano Zampini 3739911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 37409162d606SStefano Zampini used_is = ISForEdges[ncc]; 3741984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3742674ae819SStefano Zampini } else { 37439162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3744984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3745674ae819SStefano Zampini } 3746674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 37479162d606SStefano Zampini 37489162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 37499162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3750984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3751984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3752674ae819SStefano Zampini if (nnsp_has_cnst) { 37535b08dc53SStefano Zampini PetscScalar quad_value; 37549162d606SStefano Zampini 37559162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 37569162d606SStefano Zampini idxs_copied = PETSC_TRUE; 37579162d606SStefano Zampini 3758a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3759674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3760a773dcb8SStefano Zampini } else { 3761a773dcb8SStefano Zampini quad_value = 1.0; 3762a773dcb8SStefano Zampini } 3763674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 37649162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3765674ae819SStefano Zampini } 37669162d606SStefano Zampini temp_constraints++; 3767674ae819SStefano Zampini total_counts++; 3768674ae819SStefano Zampini } 3769674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3770984c4197SStefano Zampini PetscReal real_value; 37719162d606SStefano Zampini PetscScalar *ptr_to_data; 37729162d606SStefano Zampini 3773984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 37749162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3775674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 37769162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3777674ae819SStefano Zampini } 3778984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3779984c4197SStefano Zampini /* check if array is null on the connected component */ 3780e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 37819162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 37825b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3783674ae819SStefano Zampini temp_constraints++; 3784674ae819SStefano Zampini total_counts++; 37859162d606SStefano Zampini if (!idxs_copied) { 37869162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 37879162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3788674ae819SStefano Zampini } 3789674ae819SStefano Zampini } 37909162d606SStefano Zampini } 37919162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 379245a1bb75SStefano Zampini valid_constraints = temp_constraints; 3793eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3794a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 37959162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 37969162d606SStefano Zampini 37979162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3798a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 37999162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3800a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 38019162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3802a773dcb8SStefano Zampini } else { /* perform SVD */ 3803984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 38049162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3805674ae819SStefano Zampini 3806674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3807984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3808984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3809984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3810984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3811984c4197SStefano Zampini from that computed using LAPACKgesvd 3812984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3813984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3814984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3815674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3816e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3817984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3818674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3819674ae819SStefano Zampini for (k=0;k<j+1;k++) { 38209162d606SStefano 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)); 3821674ae819SStefano Zampini } 3822674ae819SStefano Zampini } 3823e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3824e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3825e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3826674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3827c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3828674ae819SStefano Zampini #else 3829c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3830674ae819SStefano Zampini #endif 3831674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3832984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3833984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3834674ae819SStefano Zampini j = 0; 3835984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3836674ae819SStefano Zampini total_counts = total_counts-j; 383745a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3838e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3839c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3840c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3841c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3842c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3843c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3844c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3845674ae819SStefano Zampini if (j<temp_constraints) { 3846984c4197SStefano Zampini PetscInt ii; 3847984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3848674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38499162d606SStefano 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)); 3850674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3851984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3852674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 38539162d606SStefano 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]; 3854674ae819SStefano Zampini } 3855674ae819SStefano Zampini } 3856674ae819SStefano Zampini } 3857674ae819SStefano Zampini #else /* on missing GESVD */ 3858e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3859e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3860b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3861674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3862674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 38639162d606SStefano 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)); 3864674ae819SStefano Zampini #else 38659162d606SStefano 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)); 3866674ae819SStefano Zampini #endif 3867984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3868674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3869984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3870e310c8b4SStefano Zampini k = temp_constraints; 3871e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3872674ae819SStefano Zampini j = 0; 3873e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 387445a1bb75SStefano Zampini valid_constraints = k-j; 3875911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3876984c4197SStefano Zampini #endif /* on missing GESVD */ 3877674ae819SStefano Zampini } 3878a773dcb8SStefano Zampini } 38799162d606SStefano Zampini /* update pointers information */ 38809162d606SStefano Zampini if (valid_constraints) { 38819162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 38829162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 38839162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 38849162d606SStefano Zampini /* set change_of_basis flag */ 388545a1bb75SStefano Zampini if (boolforchange) { 3886b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 38879162d606SStefano Zampini } 3888b3d85658SStefano Zampini total_counts_cc++; 388945a1bb75SStefano Zampini } 389045a1bb75SStefano Zampini } 3891984c4197SStefano Zampini /* free workspace */ 38928f1c130eSStefano Zampini if (!skip_lapack) { 3893984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3894984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3895984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3896984c4197SStefano Zampini #endif 3897984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3898984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3899984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3900984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3901984c4197SStefano Zampini #endif 3902984c4197SStefano Zampini } 3903984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3904984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3905984c4197SStefano Zampini } 3906984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3907cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3908cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3909cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3910cf5a6209SStefano Zampini } 3911cf5a6209SStefano Zampini if (n_ISForFaces) { 3912cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3913cf5a6209SStefano Zampini } 3914cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3915cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3916cf5a6209SStefano Zampini } 3917cf5a6209SStefano Zampini if (n_ISForEdges) { 3918cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3919cf5a6209SStefano Zampini } 3920cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 392108122e43SStefano Zampini } else { 392208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3923984c4197SStefano Zampini 392408122e43SStefano Zampini total_counts = 0; 392508122e43SStefano Zampini n_vertices = 0; 3926d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3927d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 392808122e43SStefano Zampini } 392908122e43SStefano Zampini max_constraints = 0; 39309162d606SStefano Zampini total_counts_cc = 0; 393108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 393208122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 39339162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 393408122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 393508122e43SStefano Zampini } 39369162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 39379162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 39389162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 39399162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 394074d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 39419162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 39429162d606SStefano Zampini total_counts_cc = 0; 39439162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 39449162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 39459162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 394608122e43SStefano Zampini } 394708122e43SStefano Zampini } 39489162d606SStefano Zampini #if 0 39499162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 39509162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 39519162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 39529162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 39539162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 39549162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 39559162d606SStefano Zampini } 39569162d606SStefano Zampini printf("\n"); 39579162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 39589162d606SStefano Zampini } 39591b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 39608bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 39611b968477SStefano Zampini } 39621b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 39638bec7fa6SStefano 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]); 39641b968477SStefano Zampini } 396508122e43SStefano Zampini #endif 396608122e43SStefano Zampini 39678bec7fa6SStefano Zampini max_size_of_constraint = 0; 39689162d606SStefano 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]); 39699162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 397008122e43SStefano Zampini /* Change of basis */ 3971b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 397208122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 397308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 397408122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3975b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 397608122e43SStefano Zampini } 397708122e43SStefano Zampini } 397808122e43SStefano Zampini } 397908122e43SStefano Zampini } 3980984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 39814f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 398208122e43SStefano Zampini 39839162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 39849162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 39856c4ed002SBarry 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); 3986674ae819SStefano Zampini 3987674ae819SStefano Zampini /* Create constraint matrix */ 3988674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 398916f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3990984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3991984c4197SStefano Zampini 3992984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3993a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3994a717540cSStefano Zampini qr_needed = PETSC_FALSE; 399574d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3996984c4197SStefano Zampini total_primal_vertices=0; 3997b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 39989162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 39999162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 400072b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 40019162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 4002b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 400364efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 40049162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 40059162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 4006a717540cSStefano Zampini } 4007b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 400891af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 4009a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 4010a717540cSStefano Zampini qr_needed = PETSC_TRUE; 4011a717540cSStefano Zampini } 4012fa434743SStefano Zampini } else { 4013b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 4014fa434743SStefano Zampini } 4015a717540cSStefano Zampini } 4016b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 4017b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 4018674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 401970022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4020b3d85658SStefano Zampini 40214f1b2e48SStefano 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); 40220e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 40230e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 4024984c4197SStefano Zampini 4025984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 402674d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 4027785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 4028984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 402974d5cdf7SStefano Zampini 4030984c4197SStefano Zampini j = total_primal_vertices; 403174d5cdf7SStefano Zampini total_counts = total_primal_vertices; 4032b3d85658SStefano Zampini cum = total_primal_vertices; 40339162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 40344641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 4035b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 4036b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 4037b3d85658SStefano Zampini cum++; 40389162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 403974d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 404074d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 404174d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 404274d5cdf7SStefano Zampini } 40439162d606SStefano Zampini j += constraints_n[i]; 4044674ae819SStefano Zampini } 4045674ae819SStefano Zampini } 4046674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 4047674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 4048088faed8SStefano Zampini 4049674ae819SStefano Zampini /* set values in constraint matrix */ 4050984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 40510e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4052674ae819SStefano Zampini } 4053984c4197SStefano Zampini total_counts = total_primal_vertices; 40549162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 40554641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 40569162d606SStefano Zampini PetscInt *cols; 40579162d606SStefano Zampini 40589162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 40599162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 40609162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 40619162d606SStefano Zampini PetscInt row = total_counts+k; 40629162d606SStefano Zampini PetscScalar *vals; 40639162d606SStefano Zampini 40649162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 40659162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 40669162d606SStefano Zampini } 40679162d606SStefano Zampini total_counts += constraints_n[i]; 4068674ae819SStefano Zampini } 4069674ae819SStefano Zampini } 4070674ae819SStefano Zampini /* assembling */ 4071674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4072674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4073088faed8SStefano Zampini 4074984c4197SStefano Zampini /* 40756a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4076984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 4077f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 4078984c4197SStefano Zampini */ 4079674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 4080674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 4081026de310SStefano Zampini /* dual and primal dofs on a single cc */ 4082984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 4083984c4197SStefano Zampini /* working stuff for GEQRF */ 408481d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 4085984c4197SStefano Zampini PetscBLASInt lqr_work; 4086984c4197SStefano Zampini /* working stuff for UNGQR */ 4087984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 4088984c4197SStefano Zampini PetscBLASInt lgqr_work; 4089984c4197SStefano Zampini /* working stuff for TRTRS */ 4090984c4197SStefano Zampini PetscScalar *trs_rhs; 40913f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 4092984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 4093984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 4094984c4197SStefano Zampini PetscScalar *start_vals; 4095984c4197SStefano Zampini /* working stuff for values insertion */ 40964641a718SStefano Zampini PetscBT is_primal; 409764efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 4098906d46d4SStefano Zampini /* matrix sizes */ 4099906d46d4SStefano Zampini PetscInt global_size,local_size; 4100906d46d4SStefano Zampini /* temporary change of basis */ 4101906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 4102cf5a6209SStefano Zampini /* extra space for debugging */ 4103cf5a6209SStefano Zampini PetscScalar *dbg_work; 4104984c4197SStefano Zampini 4105906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 4106906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 410716f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 4108bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 4109906d46d4SStefano Zampini /* nonzeros for local mat */ 4110bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 41111dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4112bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 41131dd7afcfSStefano Zampini } else { 41141dd7afcfSStefano Zampini const PetscInt *ii; 41151dd7afcfSStefano Zampini PetscInt n; 41161dd7afcfSStefano Zampini PetscBool flg_row; 41171dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 41181dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 41191dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 41201dd7afcfSStefano Zampini } 41219162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 4122a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 41239162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 4124a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 41259162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 4126a717540cSStefano Zampini } else { 41279162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 41289162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 4129a717540cSStefano Zampini } 4130a717540cSStefano Zampini } 4131a717540cSStefano Zampini } 4132906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 4133bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 41341dd7afcfSStefano Zampini /* Set interior change in the matrix */ 41351dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4136bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 4137906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 4138a717540cSStefano Zampini } 41391dd7afcfSStefano Zampini } else { 41401dd7afcfSStefano Zampini const PetscInt *ii,*jj; 41411dd7afcfSStefano Zampini PetscScalar *aa; 41421dd7afcfSStefano Zampini PetscInt n; 41431dd7afcfSStefano Zampini PetscBool flg_row; 41441dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 41451dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 41461dd7afcfSStefano Zampini for (i=0;i<n;i++) { 41471dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 41481dd7afcfSStefano Zampini } 41491dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 41501dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 41511dd7afcfSStefano Zampini } 4152a717540cSStefano Zampini 4153a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4154a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4155a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4156a717540cSStefano Zampini } 4157a717540cSStefano Zampini 4158a717540cSStefano Zampini 4159a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 4160a717540cSStefano Zampini /* 4161a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 4162a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 4163a717540cSStefano Zampini 4164a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 4165a717540cSStefano Zampini 4166a6b551f4SStefano 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) 4167a6b551f4SStefano Zampini 4168a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 4169a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 4170a717540cSStefano Zampini | ... | 4171a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 4172a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 4173a717540cSStefano Zampini 4174a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 4175a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 4176a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 4177a6b551f4SStefano Zampini 4178a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 4179a717540cSStefano Zampini */ 4180a717540cSStefano Zampini if (qr_needed) { 4181984c4197SStefano Zampini /* space to store Q */ 4182854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 4183984c4197SStefano Zampini /* first we issue queries for optimal work */ 41843f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 41853f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 41863f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4187984c4197SStefano Zampini lqr_work = -1; 41883f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 4189984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 4190984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 4191785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 4192984c4197SStefano Zampini lgqr_work = -1; 41933f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 41943f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 41953f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 41963f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 41973f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 41983f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 4199984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 4200984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 4201785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 4202984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 4203785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 4204984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 4205785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 4206a717540cSStefano Zampini /* allocating workspace for check */ 4207a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4208cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 4209a717540cSStefano Zampini } 4210a717540cSStefano Zampini } 4211984c4197SStefano Zampini /* array to store whether a node is primal or not */ 42124641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 4213473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 42140e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 42156c4ed002SBarry 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); 421639e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 421739e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 421839e2fb2aSStefano Zampini } 421939e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 4220984c4197SStefano Zampini 4221a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 42229162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 42239162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 42244641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 4225984c4197SStefano Zampini /* get constraint info */ 42269162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 4227984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 4228984c4197SStefano Zampini 4229984c4197SStefano Zampini if (pcbddc->dbg_flag) { 42309162d606SStefano 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); 4231674ae819SStefano Zampini } 4232984c4197SStefano Zampini 4233fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 4234a717540cSStefano Zampini 4235a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 4236a717540cSStefano Zampini if (pcbddc->dbg_flag) { 42379162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4238a717540cSStefano Zampini } 4239984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 42409162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4241984c4197SStefano Zampini 4242984c4197SStefano Zampini /* compute QR decomposition of constraints */ 42433f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 42443f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 42453f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4246674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 42473f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 4248984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 4249674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4250984c4197SStefano Zampini 4251984c4197SStefano Zampini /* explictly compute R^-T */ 4252984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 4253984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 42543f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 42553f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 42563f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 42573f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 4258984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 42593f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 4260984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 4261984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4262984c4197SStefano Zampini 4263a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 42643f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 42653f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 42663f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 42673f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4268984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 42693f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 4270984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 4271984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4272984c4197SStefano Zampini 4273984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 4274984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 4275984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 42763f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 42773f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 42783f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 42793f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 42803f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 42813f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 4282984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 42839162d606SStefano 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)); 4284984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 42859162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4286984c4197SStefano Zampini 4287984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 42889162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 4289984c4197SStefano Zampini /* insert cols for primal dofs */ 4290984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 4291984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 42929162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4293906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4294984c4197SStefano Zampini } 4295984c4197SStefano Zampini /* insert cols for dual dofs */ 4296984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 42979162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 4298984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 42999162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4300906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4301984c4197SStefano Zampini j++; 4302674ae819SStefano Zampini } 4303674ae819SStefano Zampini } 4304984c4197SStefano Zampini 4305984c4197SStefano Zampini /* check change of basis */ 4306984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4307984c4197SStefano Zampini PetscInt ii,jj; 4308984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 4309c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 4310c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4311c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 4312c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4313c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 4314c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 4315984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4316cf5a6209SStefano 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)); 4317984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4318984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4319984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4320cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 4321cf5a6209SStefano 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; 4322674ae819SStefano Zampini } 4323674ae819SStefano Zampini } 4324984c4197SStefano Zampini if (!valid_qr) { 432522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 4326984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4327984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4328cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 4329cf5a6209SStefano 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])); 4330674ae819SStefano Zampini } 4331cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 4332cf5a6209SStefano 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])); 4333984c4197SStefano Zampini } 4334984c4197SStefano Zampini } 4335984c4197SStefano Zampini } 4336674ae819SStefano Zampini } else { 433722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 4338674ae819SStefano Zampini } 4339674ae819SStefano Zampini } 4340a717540cSStefano Zampini } else { /* simple transformation block */ 4341a717540cSStefano Zampini PetscInt row,col; 4342a6b551f4SStefano Zampini PetscScalar val,norm; 4343a6b551f4SStefano Zampini 4344a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 43459162d606SStefano 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)); 4346a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 43479162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 43489162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4349bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 43509162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 4351906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 43529162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 4353a717540cSStefano Zampini } else { 4354a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 43559162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4356a717540cSStefano Zampini if (row != col) { 43579162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 4358a717540cSStefano Zampini } else { 43599162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 4360a717540cSStefano Zampini } 4361906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 4362a717540cSStefano Zampini } 4363a717540cSStefano Zampini } 4364a717540cSStefano Zampini } 436598a51de6SStefano Zampini if (pcbddc->dbg_flag) { 436622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 4367a717540cSStefano Zampini } 4368674ae819SStefano Zampini } 4369984c4197SStefano Zampini } else { 4370984c4197SStefano Zampini if (pcbddc->dbg_flag) { 43719162d606SStefano 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); 4372674ae819SStefano Zampini } 4373674ae819SStefano Zampini } 4374674ae819SStefano Zampini } 4375a717540cSStefano Zampini 4376a717540cSStefano Zampini /* free workspace */ 4377a717540cSStefano Zampini if (qr_needed) { 4378984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4379cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 4380984c4197SStefano Zampini } 4381984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 4382984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 4383984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 4384984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 4385984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 4386674ae819SStefano Zampini } 4387a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 4388906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4389906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4390906d46d4SStefano Zampini 4391906d46d4SStefano Zampini /* assembling of global change of variable */ 439288c03ad3SStefano Zampini if (!pcbddc->fake_change) { 4393bbb9e6c6SStefano Zampini Mat tmat; 439416f15bc4SStefano Zampini PetscInt bs; 439516f15bc4SStefano Zampini 4396906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4397906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4398bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4399bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 4400bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4401bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 440216f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 440316f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 4404906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4405bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 4406bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4407bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4408bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4409bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4410e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4411e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4412bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 4413bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 441488c03ad3SStefano Zampini 4415906d46d4SStefano Zampini /* check */ 4416906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4417906d46d4SStefano Zampini PetscReal error; 4418906d46d4SStefano Zampini Vec x,x_change; 4419906d46d4SStefano Zampini 4420906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 4421906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 4422906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 4423906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 4424e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4425e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4426bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4427e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4428e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4429906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4430906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4431906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4432906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4433bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4434906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4435906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4436906d46d4SStefano Zampini } 4437b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4438b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4439b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4440bf3a8328SStefano Zampini 4441bf3a8328SStefano Zampini if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) { 4442bf3a8328SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints");CHKERRQ(ierr); 4443bf3a8328SStefano Zampini } 4444b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 4445ac632422SStefano Zampini Mat S_new,tmat; 4446bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 4447bbb9e6c6SStefano Zampini 4448bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 44496816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4450bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4451bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 4452bf3a8328SStefano Zampini IS is_V; 4453b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4454b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4455b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4456b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4457b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4458bf3a8328SStefano Zampini } 4459bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4460ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4461b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4462ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4463bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4464bf3a8328SStefano Zampini const PetscScalar *array; 4465bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 4466bf3a8328SStefano Zampini PetscInt i,n_V; 4467bf3a8328SStefano Zampini 4468b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4469b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4470b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4471b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4472b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4473b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4474b087196eSStefano Zampini PetscScalar val; 4475b087196eSStefano Zampini PetscInt idx; 4476b087196eSStefano Zampini 4477b087196eSStefano Zampini idx = idxs_V[i]; 4478b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4479b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4480b087196eSStefano Zampini } 4481b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4482b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4483bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4484bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4485bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4486bf3a8328SStefano Zampini } 4487ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4488ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4489ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4490ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4491b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4492ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4493bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4494b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4495bf3a8328SStefano Zampini } 4496ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4497ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4498ac632422SStefano Zampini } 4499b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 450088c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4501b96c3477SStefano Zampini } 4502c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 4503c9db6a07SStefano Zampini if (sub_schurs->change) { 4504c9db6a07SStefano Zampini PetscInt i; 4505c9db6a07SStefano Zampini 4506c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4507c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 4508c9db6a07SStefano Zampini } 4509c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 4510c9db6a07SStefano Zampini } 4511b96c3477SStefano Zampini } 451216909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 451316909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 451416909a7fSStefano Zampini } else { 4515906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 451616909a7fSStefano Zampini } 45171dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 451827b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 451972b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 452072b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 452172b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 452272b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 452372b8c272SStefano Zampini } 45241dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 452527b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 4526b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4527b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4528906d46d4SStefano Zampini } else { 45291dd7afcfSStefano Zampini Mat benign_global = NULL; 453027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 45311dd7afcfSStefano Zampini Mat tmat; 45321dd7afcfSStefano Zampini 45331dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 45341dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 45351dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 45361dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 45371dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 45381dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 45391dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 45401dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 45411dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 45421dd7afcfSStefano Zampini if (pcbddc->benign_change) { 45431dd7afcfSStefano Zampini Mat M; 45441dd7afcfSStefano Zampini 45451dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 45461dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 45471dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 45481dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4549906d46d4SStefano Zampini } else { 45501dd7afcfSStefano Zampini Mat eye; 45511dd7afcfSStefano Zampini PetscScalar *array; 45521dd7afcfSStefano Zampini 45531dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 45541dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 45551dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 45561dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 4557906d46d4SStefano Zampini } 45581dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 45591dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45601dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45611dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 45621dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 45631dd7afcfSStefano Zampini } 45641dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 45651dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 45661dd7afcfSStefano Zampini } 45671dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 45681dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 45691dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 457027b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 45711dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 45721dd7afcfSStefano Zampini } 45731dd7afcfSStefano Zampini } 457416909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 457516909a7fSStefano Zampini IS is_global; 457616909a7fSStefano Zampini const PetscInt *gidxs; 457716909a7fSStefano Zampini 457816909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 457916909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 458016909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 458116909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 458216909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 458316909a7fSStefano Zampini } 45841dd7afcfSStefano Zampini } 45851dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 45861dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 4587b9b85e73SStefano Zampini } 4588a717540cSStefano Zampini 458972b8c272SStefano Zampini if (!pcbddc->fake_change) { 45904f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 45914f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 45924f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 45934f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4594019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4595019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4596019a44ceSStefano Zampini pcbddc->local_primal_size++; 4597019a44ceSStefano Zampini } 4598019a44ceSStefano Zampini 4599019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4600727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4601727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 46029f47a83aSStefano 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); 4603c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 46040e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 46059f47a83aSStefano 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); 4606727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4607727cdba6SStefano Zampini } 46080e6343abSStefano Zampini } 4609727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4610b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 461172b8c272SStefano Zampini } 461272b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4613727cdba6SStefano Zampini 4614a717540cSStefano Zampini /* flush dbg viewer */ 4615b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4616b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4617b8ffe317SStefano Zampini } 4618a717540cSStefano Zampini 4619e310c8b4SStefano Zampini /* free workspace */ 4620a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 46214641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 462208122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 46239162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 46249162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 462508122e43SStefano Zampini } else { 46269162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 46279162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 46289162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 462908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 463008122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 46319162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 46329162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 463308122e43SStefano Zampini } 4634674ae819SStefano Zampini PetscFunctionReturn(0); 4635674ae819SStefano Zampini } 4636674ae819SStefano Zampini 4637674ae819SStefano Zampini #undef __FUNCT__ 4638674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4639674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4640674ae819SStefano Zampini { 4641674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4642674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4643674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 464414f95afaSStefano Zampini PetscInt ierr,i,N; 4645674ae819SStefano Zampini 4646674ae819SStefano Zampini PetscFunctionBegin; 46478e61c736SStefano Zampini /* Reset previously computed graph */ 46488e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4649674ae819SStefano Zampini /* Init local Graph struct */ 46507fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 46513bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4652674ae819SStefano Zampini 4653575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 46545099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 46555099eff2SStefano 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); 4656575ad6abSStefano Zampini } 46579577ea80SStefano Zampini 4658674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 4659d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 46604d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 46614d379d7bSStefano Zampini PetscInt nvtxs; 4662e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4663674ae819SStefano Zampini 46642fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 46652fffb893SStefano Zampini if (flg_row) { 46664d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4667b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 46682fffb893SStefano Zampini } 46692fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4670674ae819SStefano Zampini } 46719b28b941SStefano Zampini if (pcbddc->dbg_flag) { 46729b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4673674ae819SStefano Zampini } 4674674ae819SStefano Zampini 4675674ae819SStefano Zampini /* Setup of Graph */ 467614f95afaSStefano 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); 4677674ae819SStefano Zampini 46784f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 46794f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 46804f1b2e48SStefano Zampini PetscInt *local_subs; 46814f1b2e48SStefano Zampini 46824f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 46834f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 46844f1b2e48SStefano Zampini const PetscInt *idxs; 46854f1b2e48SStefano Zampini PetscInt nl,j; 46864f1b2e48SStefano Zampini 46874f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 46884f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 46894f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 46904f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 46914f1b2e48SStefano Zampini } 46924f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 46934f1b2e48SStefano Zampini } 46944f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 46954f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 46964f1b2e48SStefano Zampini } 46974f1b2e48SStefano Zampini 4698674ae819SStefano Zampini /* Graph's connected components analysis */ 4699674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4700674ae819SStefano Zampini PetscFunctionReturn(0); 4701674ae819SStefano Zampini } 4702674ae819SStefano Zampini 4703dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 4704674ae819SStefano Zampini #undef __FUNCT__ 4705674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 4706dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 4707674ae819SStefano Zampini { 4708dc456d91SStefano Zampini PetscSF sf; 4709dc456d91SStefano Zampini PetscLayout map; 4710dc456d91SStefano Zampini const PetscInt *idxs; 4711dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4712dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4713dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4714dc456d91SStefano Zampini PetscMPIInt commsize; 4715674ae819SStefano Zampini PetscBool first_found; 4716674ae819SStefano Zampini PetscErrorCode ierr; 4717674ae819SStefano Zampini 4718674ae819SStefano Zampini PetscFunctionBegin; 4719dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4720dc456d91SStefano Zampini if (subset_mult) { 4721dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4722dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4723dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4724674ae819SStefano Zampini } 4725dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4726dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4727dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4728dc456d91SStefano Zampini for (i=0;i<n;i++) { 4729dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4730dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4731674ae819SStefano Zampini } 4732dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4733b2566f29SBarry Smith ierr = MPIU_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4734dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4735dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4736dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4737dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4738dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4739dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4740dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4741dc456d91SStefano Zampini 4742dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4743dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4744dc456d91SStefano Zampini if (subset_mult) { 4745dc456d91SStefano Zampini const PetscInt* idxs_mult; 4746dc456d91SStefano Zampini 4747dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4748dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4749dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4750674ae819SStefano Zampini } else { 4751dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4752674ae819SStefano Zampini } 4753dc456d91SStefano Zampini /* local size of new subset */ 4754dc456d91SStefano Zampini n_n = 0; 4755dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4756dc456d91SStefano Zampini 4757dc456d91SStefano Zampini /* global indexes in layout */ 4758dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4759dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4760dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4761dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4762dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4763dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4764dc456d91SStefano Zampini 4765dc456d91SStefano Zampini /* reduce from leaves to roots */ 4766dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 476764a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 476864a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4769dc456d91SStefano Zampini 4770dc456d91SStefano Zampini /* count indexes in local part of layout */ 4771674ae819SStefano Zampini nlocals = 0; 4772674ae819SStefano Zampini first_index = -1; 4773674ae819SStefano Zampini first_found = PETSC_FALSE; 4774dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4775dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4776674ae819SStefano Zampini first_found = PETSC_TRUE; 4777674ae819SStefano Zampini first_index = i; 4778674ae819SStefano Zampini } 4779dc456d91SStefano Zampini nlocals += root_data[i]; 4780674ae819SStefano Zampini } 4781dc456d91SStefano Zampini 4782dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 47835fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4784dc456d91SStefano Zampini start = 0; 478564a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 47865fa240b1SStefano Zampini #else 478764a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 47885fa240b1SStefano Zampini start = start-nlocals; 47895fa240b1SStefano Zampini #endif 47905fa240b1SStefano Zampini 4791dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4792dc456d91SStefano Zampini *N_n = start + nlocals; 4793dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4794dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4795674ae819SStefano Zampini } 47965fa240b1SStefano Zampini 47975fa240b1SStefano Zampini /* adapt root data with cumulative */ 4798674ae819SStefano Zampini if (first_found) { 4799dc456d91SStefano Zampini PetscInt old_index; 4800dc456d91SStefano Zampini 4801dc456d91SStefano Zampini root_data[first_index] += start; 4802674ae819SStefano Zampini old_index = first_index; 4803dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4804dc456d91SStefano Zampini if (root_data[i]) { 4805dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4806674ae819SStefano Zampini old_index = i; 4807674ae819SStefano Zampini } 4808674ae819SStefano Zampini } 4809674ae819SStefano Zampini } 4810dc456d91SStefano Zampini 4811dc456d91SStefano Zampini /* from roots to leaves */ 4812dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4813dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4814dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4815dc456d91SStefano Zampini 4816dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4817dc456d91SStefano Zampini if (subset_mult) { 4818dc456d91SStefano Zampini const PetscInt* idxs_mult; 4819dc456d91SStefano Zampini PetscInt cum; 4820dc456d91SStefano Zampini 4821dc456d91SStefano Zampini cum = 0; 4822dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4823dc456d91SStefano Zampini for (i=0;i<n;i++) { 4824dc456d91SStefano Zampini PetscInt j; 4825dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4826674ae819SStefano Zampini } 4827dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4828674ae819SStefano Zampini } else { 4829dc456d91SStefano Zampini for (i=0;i<n;i++) { 4830dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4831674ae819SStefano Zampini } 4832674ae819SStefano Zampini } 4833dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4834dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4835674ae819SStefano Zampini PetscFunctionReturn(0); 4836674ae819SStefano Zampini } 48379a7d3425SStefano Zampini 48389a7d3425SStefano Zampini #undef __FUNCT__ 48399a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 48409a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 48419a7d3425SStefano Zampini { 48429a7d3425SStefano Zampini PetscInt i,j; 48439a7d3425SStefano Zampini PetscScalar *alphas; 48449a7d3425SStefano Zampini PetscErrorCode ierr; 48459a7d3425SStefano Zampini 48469a7d3425SStefano Zampini PetscFunctionBegin; 48479a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4848785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 48499a7d3425SStefano Zampini for (i=0;i<n;i++) { 48509a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 48519a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 48529a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 48539a7d3425SStefano Zampini } 48549a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 48559a7d3425SStefano Zampini PetscFunctionReturn(0); 48569a7d3425SStefano Zampini } 48579a7d3425SStefano Zampini 4858e7931f94SStefano Zampini #undef __FUNCT__ 485970cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 486057de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 4861e7931f94SStefano Zampini { 486257de7509SStefano Zampini Mat A; 4863e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4864e7931f94SStefano Zampini PetscMPIInt size,rank,color; 486552e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 486652e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 486727b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 486857de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 486927b6a85dSStefano Zampini PetscInt xadj_count, *count; 487027b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 487127b6a85dSStefano Zampini PetscSubcomm psubcomm; 487227b6a85dSStefano Zampini MPI_Comm subcomm; 487352e5ac9dSStefano Zampini PetscErrorCode ierr; 4874a57a6d2fSStefano Zampini 4875e7931f94SStefano Zampini PetscFunctionBegin; 487657de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 487757de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 487857de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 487957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 488057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 488157de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 488257de7509SStefano Zampini 488357de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 488457de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 488557de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 488657de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 488757de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 488857de7509SStefano Zampini im_active = !!(n); 488957de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 489057de7509SStefano Zampini void_procs = size - active_procs; 489157de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 489257de7509SStefano Zampini if (void_procs) { 489357de7509SStefano Zampini PetscInt ncand; 489457de7509SStefano Zampini 489557de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 489657de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 489757de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 489857de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 489957de7509SStefano Zampini if (!procs_candidates[i]) { 490057de7509SStefano Zampini procs_candidates[ncand++] = i; 490157de7509SStefano Zampini } 490257de7509SStefano Zampini } 490357de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 490457de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 490557de7509SStefano Zampini } 490657de7509SStefano Zampini 490757de7509SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix */ 490857de7509SStefano Zampini if (active_procs < *n_subdomains) { 490957de7509SStefano Zampini PetscInt issize,isidx; 491057de7509SStefano Zampini if (im_active) { 491157de7509SStefano Zampini issize = 1; 491257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 491357de7509SStefano Zampini isidx = procs_candidates[rank]; 491457de7509SStefano Zampini } else { 491557de7509SStefano Zampini isidx = rank; 491657de7509SStefano Zampini } 491757de7509SStefano Zampini } else { 491857de7509SStefano Zampini issize = 0; 491957de7509SStefano Zampini isidx = -1; 492057de7509SStefano Zampini } 492157de7509SStefano Zampini *n_subdomains = active_procs; 492257de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 4923daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 492457de7509SStefano Zampini PetscFunctionReturn(0); 492557de7509SStefano Zampini } 4926c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 4927c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 492827b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 4929e7931f94SStefano Zampini 4930e7931f94SStefano Zampini /* Get info on mapping */ 49313bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 49323bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4933e7931f94SStefano Zampini 4934e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4935785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4936e7931f94SStefano Zampini xadj[0] = 0; 4937e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4938785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4939785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 494027b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 494127b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 494227b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 494327b6a85dSStefano Zampini count[shared[i][j]] += 1; 4944e7931f94SStefano Zampini 494527b6a85dSStefano Zampini xadj_count = 0; 49462b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 494727b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 494827b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 4949d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4950d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4951d023bfaeSStefano Zampini xadj_count++; 495227b6a85dSStefano Zampini break; 495327b6a85dSStefano Zampini } 4954e7931f94SStefano Zampini } 4955e7931f94SStefano Zampini } 4956d023bfaeSStefano Zampini xadj[1] = xadj_count; 495727b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 49583bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4959e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4960e7931f94SStefano Zampini 49613837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4962e7931f94SStefano Zampini 496327b6a85dSStefano Zampini /* Restrict work on active processes only */ 496427b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 496527b6a85dSStefano Zampini if (void_procs) { 496627b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 496727b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 496827b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 496927b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 497027b6a85dSStefano Zampini } else { 497127b6a85dSStefano Zampini psubcomm = NULL; 497227b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 497327b6a85dSStefano Zampini } 497427b6a85dSStefano Zampini 497527b6a85dSStefano Zampini v_wgt = NULL; 497627b6a85dSStefano Zampini if (!color) { 4977e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4978e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4979e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4980c8587f34SStefano Zampini } else { 498152e5ac9dSStefano Zampini Mat subdomain_adj; 498252e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 498352e5ac9dSStefano Zampini MatPartitioning partitioner; 498427b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 498552e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 498657de7509SStefano Zampini PetscMPIInt size; 4987b0c7d250SStefano Zampini PetscBool aggregate; 4988b0c7d250SStefano Zampini 498927b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 499027b6a85dSStefano Zampini if (void_procs) { 499127b6a85dSStefano Zampini PetscInt prank = rank; 4992785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 499327b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 4994e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4995e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4996c8587f34SStefano Zampini } 4997e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 499827b6a85dSStefano Zampini } else { 499927b6a85dSStefano Zampini oldranks = NULL; 500027b6a85dSStefano Zampini } 5001b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 500227b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 5003b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 5004b0c7d250SStefano Zampini PetscMPIInt nrank; 5005b0c7d250SStefano Zampini PetscScalar *vals; 5006b0c7d250SStefano Zampini 500727b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 5008b0c7d250SStefano Zampini lrows = 0; 5009b0c7d250SStefano Zampini if (nrank<redprocs) { 5010b0c7d250SStefano Zampini lrows = size/redprocs; 5011b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 5012b0c7d250SStefano Zampini } 501327b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 5014b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 5015b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5016b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5017b0c7d250SStefano Zampini row = nrank; 5018b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 5019b0c7d250SStefano Zampini cols = adjncy; 5020b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 5021b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 5022b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 5023b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5024b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 502552e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 502652e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 502752e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5028b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 502927b6a85dSStefano Zampini if (use_vwgt) { 503027b6a85dSStefano Zampini Vec v; 503127b6a85dSStefano Zampini const PetscScalar *array; 503227b6a85dSStefano Zampini PetscInt nl; 503327b6a85dSStefano Zampini 503427b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 503527b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 503627b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 503727b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 503827b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 503927b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 504027b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 504122db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 504227b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 504327b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 504427b6a85dSStefano Zampini } 5045b0c7d250SStefano Zampini } else { 504627b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 504727b6a85dSStefano Zampini if (use_vwgt) { 504827b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 504927b6a85dSStefano Zampini v_wgt[0] = local_size; 505027b6a85dSStefano Zampini } 5051b0c7d250SStefano Zampini } 505222b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 5053e7931f94SStefano Zampini 5054e7931f94SStefano Zampini /* Partition */ 505527b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 5056e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 505727b6a85dSStefano Zampini if (v_wgt) { 5058e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 5059c8587f34SStefano Zampini } 506057de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 506157de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 5062e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 5063e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 506422b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 5065e7931f94SStefano Zampini 506652e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 506752e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 506852e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 506952e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 507057de7509SStefano Zampini if (!aggregate) { 507157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 507227b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 507327b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 507427b6a85dSStefano Zampini #endif 507557de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 507627b6a85dSStefano Zampini } else if (oldranks) { 5077b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 507827b6a85dSStefano Zampini } else { 507927b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 508057de7509SStefano Zampini } 508128143c3dSStefano Zampini } else { 5082b0c7d250SStefano Zampini PetscInt idxs[1]; 5083b0c7d250SStefano Zampini PetscMPIInt tag; 5084b0c7d250SStefano Zampini MPI_Request *reqs; 5085b0c7d250SStefano Zampini 5086b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 5087b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 5088b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 508927b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 509028143c3dSStefano Zampini } 509127b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 5092b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5093b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 509457de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 509527b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 509627b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 509727b6a85dSStefano Zampini #endif 509857de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 509927b6a85dSStefano Zampini } else if (oldranks) { 5100b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 510127b6a85dSStefano Zampini } else { 510227b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 5103e7931f94SStefano Zampini } 510457de7509SStefano Zampini } 510552e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5106e7931f94SStefano Zampini /* clean up */ 5107e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 510852e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 5109e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 5110e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 5111e7931f94SStefano Zampini } 511227b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 511357de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 5114e7931f94SStefano Zampini 5115e7931f94SStefano Zampini /* assemble parallel IS for sends */ 5116e7931f94SStefano Zampini i = 1; 511727b6a85dSStefano Zampini if (!color) i=0; 511857de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 5119e7931f94SStefano Zampini PetscFunctionReturn(0); 5120e7931f94SStefano Zampini } 5121e7931f94SStefano Zampini 5122e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 5123e7931f94SStefano Zampini 5124e7931f94SStefano Zampini #undef __FUNCT__ 5125e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 512657de7509SStefano 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[]) 5127e7931f94SStefano Zampini { 512870cf5478SStefano Zampini Mat local_mat; 5129e7931f94SStefano Zampini IS is_sends_internal; 51309d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 513128143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 51329d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 5133e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 5134e7931f94SStefano Zampini PetscInt* l2gmap_indices; 5135e7931f94SStefano Zampini const PetscInt* is_indices; 5136e7931f94SStefano Zampini MatType new_local_type; 5137e7931f94SStefano Zampini /* buffers */ 5138e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 513928143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 51409d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 5141e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 5142e7931f94SStefano Zampini /* MPI */ 514328143c3dSStefano Zampini MPI_Comm comm,comm_n; 514428143c3dSStefano Zampini PetscSubcomm subcomm; 5145e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 514628143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 514728143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 514828143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 514928143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 515028143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 5151e7931f94SStefano Zampini PetscErrorCode ierr; 5152e7931f94SStefano Zampini 5153e7931f94SStefano Zampini PetscFunctionBegin; 515457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5155e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 515628143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 515757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 515857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 515957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 516057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 516157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 516257de7509SStefano Zampini 516357de7509SStefano Zampini /* further checks */ 5164e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5165e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 5166e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 5167e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 5168e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 516957de7509SStefano Zampini if (reuse && *mat_n) { 517070cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 517157de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 517270cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 517328143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 517470cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 517570cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 517670cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 517770cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 517870cf5478SStefano Zampini } 5179e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 5180e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 518157de7509SStefano Zampini 5182e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 5183e7931f94SStefano Zampini if (!is_sends) { 518428143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 518557de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 5186c8587f34SStefano Zampini } else { 5187e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 5188e7931f94SStefano Zampini is_sends_internal = is_sends; 5189c8587f34SStefano Zampini } 5190e7931f94SStefano Zampini 5191e7931f94SStefano Zampini /* get comm */ 5192a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 5193e7931f94SStefano Zampini 5194e7931f94SStefano Zampini /* compute number of sends */ 5195e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 5196e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 5197e7931f94SStefano Zampini 5198e7931f94SStefano Zampini /* compute number of receives */ 5199e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 5200785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 5201e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 5202e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5203e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 5204e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 5205e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 5206e7931f94SStefano Zampini 520728143c3dSStefano Zampini /* restrict comm if requested */ 520828143c3dSStefano Zampini subcomm = 0; 520928143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 521028143c3dSStefano Zampini if (restrict_comm) { 5211779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 5212779c1cceSStefano Zampini 521328143c3dSStefano Zampini color = 0; 521453a05cb3SStefano Zampini if (restrict_full) { 521553a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 521653a05cb3SStefano Zampini } else { 521753a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 521853a05cb3SStefano Zampini } 5219b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 522028143c3dSStefano Zampini subcommsize = commsize - subcommsize; 522128143c3dSStefano Zampini /* check if reuse has been requested */ 522257de7509SStefano Zampini if (reuse) { 522328143c3dSStefano Zampini if (*mat_n) { 522428143c3dSStefano Zampini PetscMPIInt subcommsize2; 522528143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 522628143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 522728143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 522828143c3dSStefano Zampini } else { 522928143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 523028143c3dSStefano Zampini } 523128143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 5232779c1cceSStefano Zampini PetscMPIInt rank; 5233779c1cceSStefano Zampini 5234779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 523528143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 523628143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 523728143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 5238306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 523928143c3dSStefano Zampini } 524028143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 524128143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 524228143c3dSStefano Zampini } else { 524328143c3dSStefano Zampini comm_n = comm; 524428143c3dSStefano Zampini } 524528143c3dSStefano Zampini 5246e7931f94SStefano Zampini /* prepare send/receive buffers */ 5247785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 5248e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 5249785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 5250e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 525128143c3dSStefano Zampini if (nis) { 5252854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 525328143c3dSStefano Zampini } 5254e7931f94SStefano Zampini 525528143c3dSStefano Zampini /* Get data from local matrices */ 52566c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 5257e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 5258e7931f94SStefano Zampini /* 5259e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 5260e7931f94SStefano Zampini send_buffer_idxs should contain: 5261e7931f94SStefano Zampini - MatType_PRIVATE type 5262e7931f94SStefano Zampini - PetscInt size_of_l2gmap 5263e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 5264e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 5265e7931f94SStefano Zampini */ 52666c4ed002SBarry Smith else { 5267e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 52683bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 5269854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 5270e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 5271e7931f94SStefano Zampini send_buffer_idxs[1] = i; 52723bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5273e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 52743bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5275e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 5276e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5277e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 5278e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 5279c8587f34SStefano Zampini } 5280c8587f34SStefano Zampini } 5281e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 528228143c3dSStefano Zampini /* additional is (if any) */ 528328143c3dSStefano Zampini if (nis) { 528428143c3dSStefano Zampini PetscMPIInt psum; 528528143c3dSStefano Zampini PetscInt j; 528628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 528728143c3dSStefano Zampini PetscInt plen; 528828143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 528928143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 529028143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 529128143c3dSStefano Zampini } 5292854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 529328143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 529428143c3dSStefano Zampini PetscInt plen; 529528143c3dSStefano Zampini const PetscInt *is_array_idxs; 529628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 529728143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 529828143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 529928143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 530028143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 530128143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 530228143c3dSStefano Zampini } 530328143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 530428143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 530528143c3dSStefano Zampini } 530628143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 530728143c3dSStefano Zampini } 530828143c3dSStefano Zampini 5309e7931f94SStefano Zampini buf_size_idxs = 0; 5310e7931f94SStefano Zampini buf_size_vals = 0; 531128143c3dSStefano Zampini buf_size_idxs_is = 0; 5312e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5313e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 5314e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 531528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 5316e7931f94SStefano Zampini } 5317785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 5318785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 531995ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 5320e7931f94SStefano Zampini 5321e7931f94SStefano Zampini /* get new tags for clean communications */ 5322e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 5323e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 532428143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 5325e7931f94SStefano Zampini 5326e7931f94SStefano Zampini /* allocate for requests */ 5327785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 5328785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 532995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 5330785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 5331785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 533295ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 5333e7931f94SStefano Zampini 5334e7931f94SStefano Zampini /* communications */ 5335e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5336e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 533728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 5338e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5339e7931f94SStefano Zampini source_dest = onodes[i]; 5340e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 5341e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 5342e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5343e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 534428143c3dSStefano Zampini if (nis) { 534557de7509SStefano Zampini source_dest = onodes_is[i]; 534628143c3dSStefano 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); 534728143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 534828143c3dSStefano Zampini } 5349e7931f94SStefano Zampini } 5350e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5351e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 5352e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 5353e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 535428143c3dSStefano Zampini if (nis) { 535528143c3dSStefano 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); 535628143c3dSStefano Zampini } 5357e7931f94SStefano Zampini } 5358e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5359e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 5360e7931f94SStefano Zampini 5361e7931f94SStefano Zampini /* assemble new l2g map */ 5362e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5363e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 53649d30be91SStefano Zampini new_local_rows = 0; 5365e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 53669d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5367e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5368e7931f94SStefano Zampini } 53699d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 5370e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 53719d30be91SStefano Zampini new_local_rows = 0; 5372e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 53739d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 53749d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5375e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5376e7931f94SStefano Zampini } 53779d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 53789d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 5379e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 5380e7931f94SStefano Zampini 5381e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 5382e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 5383e7931f94SStefano 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) */ 5384e7931f94SStefano Zampini if (n_recvs) { 538528143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 5386e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5387e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5388e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 5389e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 5390e7931f94SStefano Zampini break; 5391e7931f94SStefano Zampini } 5392e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5393e7931f94SStefano Zampini } 5394e7931f94SStefano Zampini switch (new_local_type_private) { 539528143c3dSStefano Zampini case MATDENSE_PRIVATE: 539628143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 5397e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5398e7931f94SStefano Zampini bs = 1; 539928143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 540028143c3dSStefano Zampini new_local_type = MATSEQDENSE; 540128143c3dSStefano Zampini bs = 1; 540228143c3dSStefano Zampini } 5403e7931f94SStefano Zampini break; 5404e7931f94SStefano Zampini case MATAIJ_PRIVATE: 5405e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5406e7931f94SStefano Zampini bs = 1; 5407e7931f94SStefano Zampini break; 5408e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 5409e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 5410e7931f94SStefano Zampini break; 5411e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 5412e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 5413e7931f94SStefano Zampini break; 5414e7931f94SStefano Zampini default: 54159d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 5416e7931f94SStefano Zampini break; 5417e7931f94SStefano Zampini } 541828143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 541928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 542028143c3dSStefano Zampini bs = 1; 5421e7931f94SStefano Zampini } 5422e7931f94SStefano Zampini 542370cf5478SStefano Zampini /* create MATIS object if needed */ 542457de7509SStefano Zampini if (!reuse) { 5425e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 5426e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 542770cf5478SStefano Zampini } else { 542870cf5478SStefano Zampini /* it also destroys the local matrices */ 542957de7509SStefano Zampini if (*mat_n) { 543070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 543157de7509SStefano Zampini } else { /* this is a fake object */ 543257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 543357de7509SStefano Zampini } 543470cf5478SStefano Zampini } 543570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 5436e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 54379d30be91SStefano Zampini 54389d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 54399d30be91SStefano Zampini 54409d30be91SStefano Zampini /* Global to local map of received indices */ 54419d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 54429d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 54439d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 54449d30be91SStefano Zampini 54459d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 54469d30be91SStefano Zampini buf_size_idxs = 0; 54479d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 54489d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 54499d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 54509d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 54519d30be91SStefano Zampini } 54529d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 54539d30be91SStefano Zampini 54549d30be91SStefano Zampini /* set preallocation */ 54559d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 54569d30be91SStefano Zampini if (!newisdense) { 54579d30be91SStefano Zampini PetscInt *new_local_nnz=0; 54589d30be91SStefano Zampini 54599d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 54609d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 54619d30be91SStefano Zampini if (n_recvs) { 54629d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 54639d30be91SStefano Zampini } 54649d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 54659d30be91SStefano Zampini PetscInt j; 54669d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 54679d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 54689d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 54699d30be91SStefano Zampini } 54709d30be91SStefano Zampini } else { 54719d30be91SStefano Zampini /* TODO */ 54729d30be91SStefano Zampini } 54739d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 54749d30be91SStefano Zampini } 54759d30be91SStefano Zampini if (new_local_nnz) { 54769d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 54779d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 54789d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 54799d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 54809d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 54819d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 54829d30be91SStefano Zampini } else { 54839d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 54849d30be91SStefano Zampini } 54859d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 54869d30be91SStefano Zampini } else { 54879d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 54889d30be91SStefano Zampini } 5489e7931f94SStefano Zampini 5490e7931f94SStefano Zampini /* set values */ 5491e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 54929d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5493e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5494e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5495e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 54969d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5497e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5498e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5499e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 550028143c3dSStefano Zampini } else { 550128143c3dSStefano Zampini /* TODO */ 5502e7931f94SStefano Zampini } 5503e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5504e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5505e7931f94SStefano Zampini } 5506e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5507e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 550870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 550970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55109d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 55119d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5512e7931f94SStefano Zampini 5513dfd14d43SStefano Zampini #if 0 551428143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5515e7931f94SStefano Zampini Vec lvec,rvec; 5516e7931f94SStefano Zampini PetscReal infty_error; 5517e7931f94SStefano Zampini 55182a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5519e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5520e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5521e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 552270cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5523e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5524e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5525e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5526e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5527e7931f94SStefano Zampini } 552828143c3dSStefano Zampini #endif 5529e7931f94SStefano Zampini 553028143c3dSStefano Zampini /* assemble new additional is (if any) */ 553128143c3dSStefano Zampini if (nis) { 553228143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 553328143c3dSStefano Zampini 553428143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5535854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 553628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 553728143c3dSStefano Zampini psum = 0; 553828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 553928143c3dSStefano Zampini for (j=0;j<nis;j++) { 554028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 554128143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 554228143c3dSStefano Zampini psum += plen; 554328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 554428143c3dSStefano Zampini } 554528143c3dSStefano Zampini } 5546854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5547854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 554828143c3dSStefano Zampini for (i=1;i<nis;i++) { 554928143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 555028143c3dSStefano Zampini } 555128143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 555228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 555328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 555428143c3dSStefano Zampini for (j=0;j<nis;j++) { 555528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 555628143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 555728143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 555828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 555928143c3dSStefano Zampini } 556028143c3dSStefano Zampini } 556128143c3dSStefano Zampini for (i=0;i<nis;i++) { 556228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 556328143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 556428143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 556528143c3dSStefano Zampini } 556628143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 556728143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 556828143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 556928143c3dSStefano Zampini } 5570e7931f94SStefano Zampini /* free workspace */ 557128143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5572e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5573e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5574e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5575e7931f94SStefano Zampini if (isdense) { 5576e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5577e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5578e7931f94SStefano Zampini } else { 5579e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5580e7931f94SStefano Zampini } 558128143c3dSStefano Zampini if (nis) { 558228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 558328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 558428143c3dSStefano Zampini } 5585e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5586e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 558728143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5588e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5589e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 559028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5591e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5592e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5593e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5594e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5595e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 559628143c3dSStefano Zampini if (nis) { 559728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 559828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 559928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 560028143c3dSStefano Zampini } 560128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 560228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 560328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 560428143c3dSStefano Zampini for (i=0;i<nis;i++) { 560528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 560628143c3dSStefano Zampini } 560753a05cb3SStefano Zampini *mat_n = NULL; 560828143c3dSStefano Zampini } 5609e7931f94SStefano Zampini PetscFunctionReturn(0); 5610e7931f94SStefano Zampini } 5611a57a6d2fSStefano Zampini 561212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5613af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 561412edc857SStefano Zampini 5615c8587f34SStefano Zampini #undef __FUNCT__ 5616c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5617c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5618c8587f34SStefano Zampini { 5619c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5620c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 562120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 56229881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 562320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 56246e683305SStefano Zampini IS coarse_is,*isarray; 56256e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 562630368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5627f9eb5b7dSStefano Zampini PC pc_temp; 5628c8587f34SStefano Zampini PCType coarse_pc_type; 5629c8587f34SStefano Zampini KSPType coarse_ksp_type; 5630f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 56314f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 56326e683305SStefano Zampini Mat t_coarse_mat_is; 563357de7509SStefano Zampini PetscInt ncoarse; 563468457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 563522bc73bbSStefano Zampini PetscScalar *array; 563657de7509SStefano Zampini MatReuse coarse_mat_reuse; 563757de7509SStefano Zampini PetscBool restr, full_restr, have_void; 56389881197aSStefano Zampini PetscErrorCode ierr; 5639fdc09c96SStefano Zampini 5640c8587f34SStefano Zampini PetscFunctionBegin; 5641c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 564268457ee5SStefano 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 */ 5643fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 56445a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5645fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5646f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5647f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5648f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5649fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 565051bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 565151bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5652dc4bcba2SStefano Zampini PC pc; 5653dc4bcba2SStefano Zampini PetscBool isbddc; 5654dc4bcba2SStefano Zampini 5655dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5656dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5657dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5658dc4bcba2SStefano Zampini if (isbddc) { 565963c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 566063c961adSStefano Zampini } else { 5661727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 566263c961adSStefano Zampini } 5663fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5664fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5665fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5666f4ddd8eeSStefano Zampini } 5667fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5668fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5669f4ddd8eeSStefano Zampini } 567070cf5478SStefano Zampini /* reset any subassembling information */ 567157de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 567270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 567357de7509SStefano Zampini } 56746e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5675fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5676f4ddd8eeSStefano Zampini } 567757de7509SStefano Zampini /* assemble coarse matrix */ 567857de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 567957de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 568057de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 568157de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 568218a45a71SStefano Zampini } else { 568357de7509SStefano Zampini coarse_mat = NULL; 568457de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 56856e683305SStefano Zampini } 5686e7931f94SStefano Zampini 5687abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5688abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5689abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5690abbbba34SStefano Zampini 5691abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 569222bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 569322bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 569422bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 569522bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5696e176bc59SStefano 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); 56976e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 56986e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 56996e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5700abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5701abbbba34SStefano Zampini 570257de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 570357de7509SStefano Zampini im_active = !!(pcis->n); 570457de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 570557de7509SStefano Zampini 570657de7509SStefano Zampini /* determine number of process partecipating to coarse solver and compute subassembling pattern */ 570757de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 570857de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 570957de7509SStefano Zampini coarse_mat_is = NULL; 571057de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 571157de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 571257de7509SStefano Zampini full_restr = PETSC_TRUE; 571357de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(pcbddc->coarse_size,pcbddc->coarse_eqs_per_proc); 571457de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 571557de7509SStefano Zampini if (multilevel_requested) { 571657de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 571757de7509SStefano Zampini restr = PETSC_FALSE; 571857de7509SStefano Zampini full_restr = PETSC_FALSE; 571957de7509SStefano Zampini } else { 572057de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 572157de7509SStefano Zampini restr = PETSC_TRUE; 572257de7509SStefano Zampini full_restr = PETSC_TRUE; 572357de7509SStefano Zampini } 572457de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 572557de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 572657de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 572757de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 572857de7509SStefano Zampini PetscInt psum; 572957de7509SStefano Zampini PetscMPIInt size; 573057de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 573157de7509SStefano Zampini else psum = 0; 573257de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 573357de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 573457de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 573557de7509SStefano Zampini } 573657de7509SStefano Zampini /* determine if we can go multilevel */ 573757de7509SStefano Zampini if (multilevel_requested) { 573857de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 573957de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 574057de7509SStefano Zampini } 574157de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 574257de7509SStefano Zampini 5743e4d548c7SStefano Zampini /* dump subassembling pattern */ 5744e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 5745e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 5746e4d548c7SStefano Zampini } 5747e4d548c7SStefano Zampini 57486e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 574927b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 57506e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 57516e683305SStefano Zampini const PetscInt *idxs; 57526e683305SStefano Zampini ISLocalToGlobalMapping tmap; 57536e683305SStefano Zampini 57546e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 57550be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 57566e683305SStefano Zampini /* allocate space for temporary storage */ 5757854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5758854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 57596e683305SStefano Zampini /* allocate for IS array */ 57606e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 57616e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 576227b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 576330368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5764854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 57656e683305SStefano Zampini /* dofs splitting */ 57666e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 57676e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 57686e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 57696e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 57706e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 57716e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 57726e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 577330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 57746e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 57756e683305SStefano Zampini } 57766e683305SStefano Zampini /* neumann boundaries */ 57776e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 57786e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 57796e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 57806e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 57816e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 57826e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 57836e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 578430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 57856e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 57866e683305SStefano Zampini } 57876e683305SStefano Zampini /* free memory */ 57886e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 57896e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 57906e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 57916e683305SStefano Zampini } else { 57926e683305SStefano Zampini nis = 0; 57936e683305SStefano Zampini nisdofs = 0; 57946e683305SStefano Zampini nisneu = 0; 579530368db7SStefano Zampini nisvert = 0; 57966e683305SStefano Zampini isarray = NULL; 57976e683305SStefano Zampini } 57986e683305SStefano Zampini /* destroy no longer needed map */ 57996e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 58006e683305SStefano Zampini 580157de7509SStefano Zampini /* subassemble */ 580257de7509SStefano Zampini if (multilevel_allowed) { 580357de7509SStefano Zampini PetscBool reuse,reuser; 580457de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 580557de7509SStefano Zampini else reuse = PETSC_FALSE; 580657de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 580757de7509SStefano Zampini if (reuser) { 580857de7509SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray);CHKERRQ(ierr); 580974e2c79eSStefano Zampini } else { 581057de7509SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 581174e2c79eSStefano Zampini } 5812*1f4df5f7SStefano Zampini /* TODO: if (pcbddc->benign_have_null) -> give a hint to the coarser levels if they have to locally apply the benign trick or not */ 581374e2c79eSStefano Zampini } else { 581457de7509SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 58156e683305SStefano Zampini } 581657de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 581757de7509SStefano Zampini PetscMPIInt size; 581857de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 581957de7509SStefano Zampini if (!multilevel_allowed) { 582057de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 58216e683305SStefano Zampini } else { 582257de7509SStefano Zampini Mat A; 5823779c1cceSStefano Zampini 582457de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 582557de7509SStefano Zampini if (coarse_mat_is) { 582657de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 582757de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 582857de7509SStefano Zampini coarse_mat = coarse_mat_is; 582957de7509SStefano Zampini } 583057de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 583157de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 583257de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 5833779c1cceSStefano Zampini } 5834779c1cceSStefano Zampini } 583557de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 583657de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 58376e683305SStefano Zampini 58386e683305SStefano Zampini /* create local to global scatters for coarse problem */ 583968457ee5SStefano Zampini if (compute_vecs) { 58406e683305SStefano Zampini PetscInt lrows; 58416e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 584257de7509SStefano Zampini if (coarse_mat) { 584357de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 58446e683305SStefano Zampini } else { 58456e683305SStefano Zampini lrows = 0; 58466e683305SStefano Zampini } 58476e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 58486e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 58496e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 58506e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 58516e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 58526e683305SStefano Zampini } 58536e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 5854c8587f34SStefano Zampini 5855f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5856f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5857f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5858f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5859f9eb5b7dSStefano Zampini } else { 5860f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5861f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5862c8587f34SStefano Zampini } 5863c8587f34SStefano Zampini 58646e683305SStefano Zampini /* print some info if requested */ 58656e683305SStefano Zampini if (pcbddc->dbg_flag) { 58666e683305SStefano Zampini if (!multilevel_allowed) { 58676e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 58686e683305SStefano Zampini if (multilevel_requested) { 58696e683305SStefano 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); 58706e683305SStefano Zampini } else if (pcbddc->max_levels) { 58716e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 58726e683305SStefano Zampini } 58736e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 58746e683305SStefano Zampini } 58756e683305SStefano Zampini } 58766e683305SStefano Zampini 5877f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 587857de7509SStefano Zampini if (coarse_mat) { 58796a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 58806e683305SStefano Zampini if (pcbddc->dbg_flag) { 588157de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 58826e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 58836e683305SStefano Zampini } 5884f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5885312be037SStefano Zampini char prefix[256],str_level[16]; 5886e604994aSStefano Zampini size_t len; 588757de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5888422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5889c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5890f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 589157de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5892c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 58936e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5894c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5895c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5896e604994aSStefano Zampini /* prefix */ 5897e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5898e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5899e604994aSStefano Zampini if (!pcbddc->current_level) { 5900e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5901e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5902c8587f34SStefano Zampini } else { 5903e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5904312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5905312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 590634d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5907312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5908e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5909e604994aSStefano Zampini } 5910e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 59113e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 59123e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 59133e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 59143e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5915f9eb5b7dSStefano Zampini /* allow user customization */ 5916f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 59173e3c6dadSStefano Zampini } 59183e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 591951bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 59203e3c6dadSStefano Zampini if (nisdofs) { 59213e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 59223e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 59233e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 59243e3c6dadSStefano Zampini } 59253e3c6dadSStefano Zampini } 59263e3c6dadSStefano Zampini if (nisneu) { 59273e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 59283e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5929312be037SStefano Zampini } 593030368db7SStefano Zampini if (nisvert) { 593130368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 593230368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 593330368db7SStefano Zampini } 5934f9eb5b7dSStefano Zampini 5935f9eb5b7dSStefano Zampini /* get some info after set from options */ 5936f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5937f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 59384f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 59396e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5940f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5941f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5942f9eb5b7dSStefano Zampini } 594339f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 59444f3a063dSStefano Zampini if (isredundant) { 59454f3a063dSStefano Zampini KSP inner_ksp; 59464f3a063dSStefano Zampini PC inner_pc; 59474f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 59484f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 59494f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 59504f3a063dSStefano Zampini } 5951f9eb5b7dSStefano Zampini 595257de7509SStefano Zampini /* parameters which miss an API */ 595357de7509SStefano Zampini if (isbddc) { 5954720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 5955720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 595657de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 595727b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 595827b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 595927b6a85dSStefano Zampini pcbddc_coarse->benign_compute_nonetflux = PETSC_TRUE; 5960720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 596159e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 5962720d30f9SStefano Zampini } 5963d4d8cf7bSStefano Zampini } 59649881197aSStefano Zampini 59653301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 59665a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 59673301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 59683301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 59693301b35fSStefano Zampini } 59703301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 59713301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 59723301b35fSStefano Zampini } 59733301b35fSStefano Zampini if (pc->pmat->spd_set) { 59743301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 59753301b35fSStefano Zampini } 597627b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 597727b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 597827b6a85dSStefano Zampini } 59796e683305SStefano Zampini /* set operators */ 59805f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 59816e683305SStefano Zampini if (pcbddc->dbg_flag) { 59826e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 59836e683305SStefano Zampini } 59846e683305SStefano Zampini } 59856e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5986b1ecc7b1SStefano Zampini #if 0 5987b9b85e73SStefano Zampini { 5988b9b85e73SStefano Zampini PetscViewer viewer; 5989b9b85e73SStefano Zampini char filename[256]; 5990b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5991b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 59926a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5993b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5994f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 5995b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5996b9b85e73SStefano Zampini } 5997b9b85e73SStefano Zampini #endif 5998f9eb5b7dSStefano Zampini 5999b8ffe317SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 6000298c0119SStefano Zampini #if 0 6001b8ffe317SStefano Zampini if (pcbddc->NullSpace) { 6002b8ffe317SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 600398a51de6SStefano Zampini } 6004298c0119SStefano Zampini #endif 6005b0f5fe93SStefano Zampini /* hack */ 600698a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 600798a51de6SStefano Zampini Vec crhs,csol; 600804708bb6SStefano Zampini 6009f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 6010f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 6011f347579bSStefano Zampini if (!csol) { 60122a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 6013f9eb5b7dSStefano Zampini } 6014f347579bSStefano Zampini if (!crhs) { 60152a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 6016f347579bSStefano Zampini } 6017b0f5fe93SStefano Zampini } 6018b0f5fe93SStefano Zampini 6019b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 6020b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 6021b0f5fe93SStefano Zampini 6022b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 60234f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 60244f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 60254f1b2e48SStefano Zampini } 6026b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 6027b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 6028b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6029b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6030b0f5fe93SStefano Zampini if (coarse_mat) { 6031b0f5fe93SStefano Zampini Vec nullv; 6032b0f5fe93SStefano Zampini PetscScalar *array,*array2; 6033b0f5fe93SStefano Zampini PetscInt nl; 6034b0f5fe93SStefano Zampini 6035b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 6036b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 6037b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6038b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 6039b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 6040b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 6041b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6042b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 6043b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 6044b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 6045b0f5fe93SStefano Zampini } 6046b0f5fe93SStefano Zampini } 6047b0f5fe93SStefano Zampini 6048b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 6049b0f5fe93SStefano Zampini PetscBool ispreonly; 6050b0f5fe93SStefano Zampini 6051b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6052b0f5fe93SStefano Zampini PetscBool isnull; 6053b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 605427b6a85dSStefano Zampini if (0) { 605530368db7SStefano Zampini if (isbddc && !pcbddc->benign_saddle_point) { 6056b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 6057b0f5fe93SStefano Zampini } else { 6058b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 6059b0f5fe93SStefano Zampini } 6060b0f5fe93SStefano Zampini } else { 6061b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 6062b0f5fe93SStefano Zampini } 6063b0f5fe93SStefano Zampini } 6064b0f5fe93SStefano Zampini /* setup coarse ksp */ 6065b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 6066cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 6067cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 60686e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 6069c8587f34SStefano Zampini KSP check_ksp; 60702b510759SStefano Zampini KSPType check_ksp_type; 6071c8587f34SStefano Zampini PC check_pc; 60726e683305SStefano Zampini Vec check_vec,coarse_vec; 60736a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 60742b510759SStefano Zampini PetscInt its; 60756e683305SStefano Zampini PetscBool compute_eigs; 60766e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 60776e683305SStefano Zampini PetscInt neigs; 60788e185a42SStefano Zampini const char *prefix; 6079c8587f34SStefano Zampini 60802b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 60816e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 6082422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 608323ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6084f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 6085e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 6086e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 6087e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 60882b510759SStefano Zampini if (ispreonly) { 60892b510759SStefano Zampini check_ksp_type = KSPPREONLY; 60906e683305SStefano Zampini compute_eigs = PETSC_FALSE; 60912b510759SStefano Zampini } else { 6092cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 60936e683305SStefano Zampini compute_eigs = PETSC_TRUE; 6094c8587f34SStefano Zampini } 6095c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 60966e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 60976e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 60986e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 6099a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 6100a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 6101a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 6102a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 6103c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 6104c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 6105c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 6106c8587f34SStefano Zampini /* create random vec */ 61072701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 6108c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 6109c8587f34SStefano Zampini if (CoarseNullSpace) { 6110c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 6111c8587f34SStefano Zampini } 61126e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 6113c8587f34SStefano Zampini /* solve coarse problem */ 61146e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 6115c8587f34SStefano Zampini if (CoarseNullSpace) { 61166e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 6117c8587f34SStefano Zampini } 6118cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 61196e683305SStefano Zampini if (compute_eigs) { 6120854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 6121854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 61226e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 61236e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 61246e683305SStefano Zampini lambda_min = eigs_r[0]; 61256e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 61262701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 61272701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 6128cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 6129cbcc2c2aSStefano Zampini } 6130c8587f34SStefano Zampini } 6131c8587f34SStefano Zampini } 6132cbcc2c2aSStefano Zampini 6133c8587f34SStefano Zampini /* check coarse problem residual error */ 61346e683305SStefano Zampini if (pcbddc->dbg_flag) { 61356e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 61366e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 61376e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 6138c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 61396e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 61406e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 6141779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 61426e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 61436e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 61446e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 61456e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 6146b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6147b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 6148b0f5fe93SStefano Zampini } 61496e683305SStefano Zampini if (compute_eigs) { 61506e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 6151deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 6152c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 61536e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 61546e683305SStefano 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); 61556e683305SStefano Zampini for (i=0;i<neigs;i++) { 61566e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 6157c8587f34SStefano Zampini } 61586e683305SStefano Zampini } 61596e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 61606e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 61616e683305SStefano Zampini } 6162e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 61632701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 6164c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 61656e683305SStefano Zampini if (compute_eigs) { 61666e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 61676e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 6168c8587f34SStefano Zampini } 61696e683305SStefano Zampini } 61706e683305SStefano Zampini } 6171cbcc2c2aSStefano Zampini /* print additional info */ 6172cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 61736e683305SStefano Zampini /* waits until all processes reaches this point */ 61746e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 6175cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 6176cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6177cbcc2c2aSStefano Zampini } 6178cbcc2c2aSStefano Zampini 61792b510759SStefano Zampini /* free memory */ 6180c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 6181fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 6182c8587f34SStefano Zampini PetscFunctionReturn(0); 6183c8587f34SStefano Zampini } 6184674ae819SStefano Zampini 6185f34684f1SStefano Zampini #undef __FUNCT__ 6186f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 6187f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 6188f34684f1SStefano Zampini { 6189f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6190f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 6191f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 6192dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 6193dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 619473be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 6195dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 6196f34684f1SStefano Zampini PetscErrorCode ierr; 6197f34684f1SStefano Zampini 6198f34684f1SStefano Zampini PetscFunctionBegin; 6199f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 62006c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 6201dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 62023bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 6203dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6204dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 6205dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 6206dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 6207dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 6208dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 62096c4ed002SBarry 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); 6210dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 6211dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6212dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 6213dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6214dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6215f34684f1SStefano Zampini 6216f34684f1SStefano Zampini /* check numbering */ 6217f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 6218019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 6219dc456d91SStefano Zampini PetscInt i; 6220b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 6221f34684f1SStefano Zampini 6222f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6223f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 6224f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 62251575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6226019a44ceSStefano Zampini /* counter */ 6227019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6228019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6229019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6230019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6231019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6232019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6233f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 6234f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 6235727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6236f34684f1SStefano Zampini } 6237f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6238f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6239f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6240e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6241e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6242e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6243e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6244f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6245019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6246f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6247019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 62482c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 624975c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 6250b9b85e73SStefano Zampini set_error = PETSC_TRUE; 62512c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 62522c66d082SStefano 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); 6253f34684f1SStefano Zampini } 6254f34684f1SStefano Zampini } 6255019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6256b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 6257f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6258f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6259f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 6260f34684f1SStefano Zampini } 6261f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6262f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6263e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6264e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6265f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 6266f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 6267b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 6268ca8b9ea9SStefano Zampini PetscInt *gidxs; 6269ca8b9ea9SStefano Zampini 6270ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 62713bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 6272f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 6273f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6274f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6275f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 62764bc2dc4bSStefano 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); 6277f34684f1SStefano Zampini } 6278f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6279ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 6280f34684f1SStefano Zampini } 6281f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 62821575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6283302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 6284f34684f1SStefano Zampini } 62858bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 6286f34684f1SStefano Zampini /* get back data */ 6287f34684f1SStefano Zampini *coarse_size_n = coarse_size; 6288f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 6289674ae819SStefano Zampini PetscFunctionReturn(0); 6290674ae819SStefano Zampini } 6291674ae819SStefano Zampini 6292e456f2a8SStefano Zampini #undef __FUNCT__ 6293e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 6294a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 6295e456f2a8SStefano Zampini { 6296e456f2a8SStefano Zampini IS localis_t; 6297a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 6298e456f2a8SStefano Zampini PetscScalar *vals; 6299e456f2a8SStefano Zampini PetscErrorCode ierr; 6300e456f2a8SStefano Zampini 6301e456f2a8SStefano Zampini PetscFunctionBegin; 6302a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 6303e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 6304854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 6305e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 6306e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6307a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 6308a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 63091035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 6310a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 63111035eff8SStefano Zampini } 6312a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 6313e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6314e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6315a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 6316a7dc3881SStefano Zampini /* now compute set in local ordering */ 6317a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6318a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6319a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6320a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 6321a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6322ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6323e456f2a8SStefano Zampini lsize++; 6324e456f2a8SStefano Zampini } 6325e456f2a8SStefano Zampini } 6326854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 6327a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6328ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6329e456f2a8SStefano Zampini idxs[lsize++] = i; 6330e456f2a8SStefano Zampini } 6331e456f2a8SStefano Zampini } 6332a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6333a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 6334e456f2a8SStefano Zampini *localis = localis_t; 6335e456f2a8SStefano Zampini PetscFunctionReturn(0); 6336e456f2a8SStefano Zampini } 6337906d46d4SStefano Zampini 6338b96c3477SStefano Zampini #undef __FUNCT__ 6339b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 634008122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 6341b96c3477SStefano Zampini { 6342a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6343b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6344b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6345a64f4aa4SStefano Zampini Mat S_j; 6346b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6347b96c3477SStefano Zampini PetscBool free_used_adj; 6348b96c3477SStefano Zampini PetscErrorCode ierr; 6349b96c3477SStefano Zampini 6350b96c3477SStefano Zampini PetscFunctionBegin; 6351b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6352b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 635308122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6354b96c3477SStefano Zampini used_xadj = NULL; 6355b96c3477SStefano Zampini used_adjncy = NULL; 6356b96c3477SStefano Zampini } else { 635708122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 635808122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 635908122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 636008122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6361b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6362b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6363b96c3477SStefano Zampini } else { 63642fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6365b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6366b96c3477SStefano Zampini PetscInt nvtxs; 6367b96c3477SStefano Zampini 63682fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 63692fffb893SStefano Zampini if (flg_row) { 6370b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6371b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6372b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6373b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 63742fffb893SStefano Zampini } else { 63752fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 63762fffb893SStefano Zampini used_xadj = NULL; 63772fffb893SStefano Zampini used_adjncy = NULL; 63782fffb893SStefano Zampini } 63792fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6380b96c3477SStefano Zampini } 6381b96c3477SStefano Zampini } 6382d5574798SStefano Zampini 6383d5574798SStefano Zampini /* setup sub_schurs data */ 6384a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6385df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 6386df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 6387a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 638891af6908SStefano 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); 6389a64f4aa4SStefano Zampini } else { 63906816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 6391b7ab4a40SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE;; 6392a3df083aSStefano Zampini PetscInt benign_n; 639372b8c272SStefano Zampini Mat change = NULL; 63949d54b7f4SStefano Zampini Vec scaling = NULL; 639572b8c272SStefano Zampini IS change_primal = NULL; 6396a3df083aSStefano Zampini 63975feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 63985feab87aSStefano Zampini PetscInt n_vertices; 63995feab87aSStefano Zampini 64005feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 64012034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 64025feab87aSStefano Zampini } 640304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 640404708bb6SStefano Zampini if (!isseqaij) { 640504708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 640604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 640704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 640804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 640904708bb6SStefano Zampini } else { 6410511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 641104708bb6SStefano Zampini } 641204708bb6SStefano Zampini } 6413a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6414a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6415ca92afb2SStefano Zampini } else { 6416a3df083aSStefano Zampini benign_n = 0; 6417ca92afb2SStefano Zampini } 6418b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 6419b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 6420b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 642172b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 642222db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 6423b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 642422db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 6425b7ab4a40SStefano Zampini } 6426b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 6427b7ab4a40SStefano 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 */ 6428b7ab4a40SStefano Zampini if (need_change) { 642988c03ad3SStefano Zampini PC_IS *pcisf; 643088c03ad3SStefano Zampini PC_BDDC *pcbddcf; 643188c03ad3SStefano Zampini PC pcf; 643288c03ad3SStefano Zampini 6433e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 643488c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 643588c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 643688c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 643788c03ad3SStefano Zampini /* hacks */ 643888c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 643972b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 644072b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 644172b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 644272b8c272SStefano Zampini pcisf->n = pcis->n; 644372b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 644488c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 644588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 644688c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 644788c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 644888c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 644988c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 645072b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 645188c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 645288c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 645372b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 645472b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 645572b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 645672b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 645772b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 645888c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 645972b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 646088c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 646188c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 646288c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 646388c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 646488c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 646588c03ad3SStefano Zampini pcf->ops->destroy = NULL; 646688c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 646788c03ad3SStefano Zampini } 64689d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 646991af6908SStefano 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); 647072b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 647172b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 6472ca92afb2SStefano Zampini } 6473d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6474b96c3477SStefano Zampini 6475b96c3477SStefano Zampini /* free adjacency */ 6476b96c3477SStefano Zampini if (free_used_adj) { 6477b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6478b96c3477SStefano Zampini } 6479b96c3477SStefano Zampini PetscFunctionReturn(0); 6480b96c3477SStefano Zampini } 6481b96c3477SStefano Zampini 6482b96c3477SStefano Zampini #undef __FUNCT__ 6483b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 648408122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6485b96c3477SStefano Zampini { 6486b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6487b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6488b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6489b96c3477SStefano Zampini PCBDDCGraph graph; 6490b96c3477SStefano Zampini PetscErrorCode ierr; 6491b96c3477SStefano Zampini 6492b96c3477SStefano Zampini PetscFunctionBegin; 6493b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 649408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 64953301b35fSStefano Zampini IS verticesIS,verticescomm; 64963301b35fSStefano Zampini PetscInt vsize,*idxs; 6497b96c3477SStefano Zampini 6498b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 64993301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 65003301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 65013301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 65023301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 65033301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6504b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 65057fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 6506441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 65073301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6508b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6509b96c3477SStefano Zampini } else { 6510b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6511b96c3477SStefano Zampini } 6512e4d548c7SStefano Zampini /* print some info */ 6513e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 6514e4d548c7SStefano Zampini IS vertices; 6515e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 6516e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6517e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 6518e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 6519e4d548c7SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 6520e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6521e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6522e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 6523e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 6524e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 6525e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6526e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6527e4d548c7SStefano Zampini } 6528b96c3477SStefano Zampini 6529b96c3477SStefano Zampini /* sub_schurs init */ 6530a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6531a64f4aa4SStefano Zampini 6532b96c3477SStefano Zampini /* free graph struct */ 653308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6534b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6535b96c3477SStefano Zampini } 6536b96c3477SStefano Zampini PetscFunctionReturn(0); 6537b96c3477SStefano Zampini } 6538fa34dd3eSStefano Zampini 6539fa34dd3eSStefano Zampini #undef __FUNCT__ 6540fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6541fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6542fa34dd3eSStefano Zampini { 6543fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6544fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6545fa34dd3eSStefano Zampini PetscErrorCode ierr; 6546fa34dd3eSStefano Zampini 6547fa34dd3eSStefano Zampini PetscFunctionBegin; 6548fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6549fa34dd3eSStefano Zampini IS zerodiag = NULL; 65504f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6551fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 65524f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 655375c01103SStefano Zampini PetscReal norm; 6554fa34dd3eSStefano Zampini PetscInt i; 6555fa34dd3eSStefano Zampini 6556fa34dd3eSStefano Zampini /* B0 and B0_B */ 6557fa34dd3eSStefano Zampini if (zerodiag) { 6558fa34dd3eSStefano Zampini IS dummy; 6559fa34dd3eSStefano Zampini 65604f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 65614f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6562fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6563fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6564fa34dd3eSStefano Zampini } 6565fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6566fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6567fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6568fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6569fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6570fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6571fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6572fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6573fa34dd3eSStefano Zampini /* S_j */ 6574fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6575fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6576fa34dd3eSStefano Zampini 6577fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6578fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6579fa34dd3eSStefano Zampini /* continuous in primal space */ 6580fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6581fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6582fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6583fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 65844f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 65854f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6586fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6587fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6588fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6589fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6590fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6591fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6592fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6593fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6594fa34dd3eSStefano Zampini 6595fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6596fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6597fa34dd3eSStefano Zampini /* local with Schur */ 6598fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6599fa34dd3eSStefano Zampini if (zerodiag) { 6600fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 66014f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6602fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6603fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6604fa34dd3eSStefano Zampini } 6605fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6606fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6607fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6608fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6609fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6610fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6611fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6612fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6613fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6614fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6615fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6616fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6617fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6618fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6619fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6620fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6621fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6622fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6623fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6624fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6625fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6626fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6627fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6628fa34dd3eSStefano Zampini if (zerodiag) { 6629fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6630fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 66314f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6632fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6633fa34dd3eSStefano Zampini } 6634fa34dd3eSStefano Zampini /* BDDC */ 6635fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6636fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6637fa34dd3eSStefano Zampini 6638fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6639fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6640fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6641fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 66424f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 66434f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6644fa34dd3eSStefano Zampini } 66454f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6646fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6647fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6648fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6649fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6650fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6651fa34dd3eSStefano Zampini } 6652fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6653fa34dd3eSStefano Zampini } 6654