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__ 81f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 91f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 101f4df5f7SStefano Zampini { 111f4df5f7SStefano Zampini PetscErrorCode ierr; 121f4df5f7SStefano Zampini Vec local,global; 131f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 141f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 151f4df5f7SStefano Zampini 161f4df5f7SStefano Zampini PetscFunctionBegin; 171f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 181f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 191f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 201f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 211f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 221f4df5f7SStefano Zampini PetscInt i; 231f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 241f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 251f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 261f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 271f4df5f7SStefano Zampini } 281f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 291f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 301f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 311f4df5f7SStefano Zampini } 321f4df5f7SStefano Zampini } else { 33*986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 341f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 35*986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 36*986cdee1SStefano Zampini if (i > 1) { 37*986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 381f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 391f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 401f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 411f4df5f7SStefano Zampini } 421f4df5f7SStefano Zampini } 431f4df5f7SStefano Zampini } 44*986cdee1SStefano Zampini } 451f4df5f7SStefano Zampini 461f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 471f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 481f4df5f7SStefano Zampini } 491f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 501f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 511f4df5f7SStefano Zampini } 521f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 531f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 541f4df5f7SStefano Zampini } 551f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 561f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 571f4df5f7SStefano Zampini PetscFunctionReturn(0); 581f4df5f7SStefano Zampini } 591f4df5f7SStefano Zampini 601f4df5f7SStefano Zampini #undef __FUNCT__ 613e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 623e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 633e589ea0SStefano Zampini { 643e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 653e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 663e589ea0SStefano Zampini PetscErrorCode ierr; 673e589ea0SStefano Zampini 683e589ea0SStefano Zampini PetscFunctionBegin; 693e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 703e589ea0SStefano Zampini PetscFunctionReturn(0); 713e589ea0SStefano Zampini } 723e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 733e589ea0SStefano Zampini Vec swap; 743e589ea0SStefano Zampini 753e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 763e589ea0SStefano Zampini swap = pcbddc->work_change; 773e589ea0SStefano Zampini pcbddc->work_change = r; 783e589ea0SStefano Zampini r = swap; 793e589ea0SStefano Zampini } 803e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 813e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 823e589ea0SStefano Zampini if (pcbddc->benign_n) { 833e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 843e589ea0SStefano Zampini } else { 853e589ea0SStefano Zampini ierr = VecSet(pcis->vec2_D,0.);CHKERRQ(ierr); 863e589ea0SStefano Zampini } 873e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 883e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 893e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 903e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 913e589ea0SStefano Zampini Vec swap; 923e589ea0SStefano Zampini 933e589ea0SStefano Zampini swap = r; 943e589ea0SStefano Zampini r = pcbddc->work_change; 953e589ea0SStefano Zampini pcbddc->work_change = swap; 963e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 973e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 983e589ea0SStefano Zampini } 993e589ea0SStefano Zampini PetscFunctionReturn(0); 1003e589ea0SStefano Zampini } 1013e589ea0SStefano Zampini 1023e589ea0SStefano Zampini #undef __FUNCT__ 103a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 104a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 105a3df083aSStefano Zampini { 106a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 107a3df083aSStefano Zampini PetscErrorCode ierr; 108a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 109a3df083aSStefano Zampini 110a3df083aSStefano Zampini PetscFunctionBegin; 111a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 112a3df083aSStefano Zampini if (transpose) { 113a3df083aSStefano Zampini apply_right = ctx->apply_left; 114a3df083aSStefano Zampini apply_left = ctx->apply_right; 115a3df083aSStefano Zampini } else { 116a3df083aSStefano Zampini apply_right = ctx->apply_right; 117a3df083aSStefano Zampini apply_left = ctx->apply_left; 118a3df083aSStefano Zampini } 119a3df083aSStefano Zampini reset_x = PETSC_FALSE; 120a3df083aSStefano Zampini if (apply_right) { 121a3df083aSStefano Zampini const PetscScalar *ax; 122a3df083aSStefano Zampini PetscInt nl,i; 123a3df083aSStefano Zampini 124a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 125a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 126a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 127a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 128a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 129a3df083aSStefano Zampini PetscScalar sum,val; 130a3df083aSStefano Zampini const PetscInt *idxs; 131a3df083aSStefano Zampini PetscInt nz,j; 132a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 133a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 134a3df083aSStefano Zampini sum = 0.; 135a3df083aSStefano Zampini if (ctx->apply_p0) { 136a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 137a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 138a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 139a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 140a3df083aSStefano Zampini } 141a3df083aSStefano Zampini } else { 142a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 143a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 144a3df083aSStefano Zampini } 145a3df083aSStefano Zampini } 146a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 147a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 148a3df083aSStefano Zampini } 149a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 150a3df083aSStefano Zampini reset_x = PETSC_TRUE; 151a3df083aSStefano Zampini } 152a3df083aSStefano Zampini if (transpose) { 153a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 154a3df083aSStefano Zampini } else { 155a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 156a3df083aSStefano Zampini } 157a3df083aSStefano Zampini if (reset_x) { 158a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 159a3df083aSStefano Zampini } 160a3df083aSStefano Zampini if (apply_left) { 161a3df083aSStefano Zampini PetscScalar *ay; 162a3df083aSStefano Zampini PetscInt i; 163a3df083aSStefano Zampini 164a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 165a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 166a3df083aSStefano Zampini PetscScalar sum,val; 167a3df083aSStefano Zampini const PetscInt *idxs; 168a3df083aSStefano Zampini PetscInt nz,j; 169a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 170a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 171a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 172a3df083aSStefano Zampini if (ctx->apply_p0) { 173a3df083aSStefano Zampini sum = 0.; 174a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 175a3df083aSStefano Zampini sum += ay[idxs[j]]; 176a3df083aSStefano Zampini ay[idxs[j]] += val; 177a3df083aSStefano Zampini } 178a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 179a3df083aSStefano Zampini } else { 180a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 181a3df083aSStefano Zampini ay[idxs[j]] += val; 182a3df083aSStefano Zampini } 183a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 184a3df083aSStefano Zampini } 185a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 186a3df083aSStefano Zampini } 187a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 188a3df083aSStefano Zampini } 189a3df083aSStefano Zampini PetscFunctionReturn(0); 190a3df083aSStefano Zampini } 191a3df083aSStefano Zampini 192a3df083aSStefano Zampini #undef __FUNCT__ 193a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 194a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 195a3df083aSStefano Zampini { 196a3df083aSStefano Zampini PetscErrorCode ierr; 197a3df083aSStefano Zampini 198a3df083aSStefano Zampini PetscFunctionBegin; 199a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 200a3df083aSStefano Zampini PetscFunctionReturn(0); 201a3df083aSStefano Zampini } 202a3df083aSStefano Zampini 203a3df083aSStefano Zampini #undef __FUNCT__ 204a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 205a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 206a3df083aSStefano Zampini { 207a3df083aSStefano Zampini PetscErrorCode ierr; 208a3df083aSStefano Zampini 209a3df083aSStefano Zampini PetscFunctionBegin; 210a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 211a3df083aSStefano Zampini PetscFunctionReturn(0); 212a3df083aSStefano Zampini } 213a3df083aSStefano Zampini 214a3df083aSStefano Zampini #undef __FUNCT__ 215a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 216a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 217a3df083aSStefano Zampini { 218a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 219a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 220a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 221a3df083aSStefano Zampini PetscErrorCode ierr; 222a3df083aSStefano Zampini 223a3df083aSStefano Zampini PetscFunctionBegin; 224a3df083aSStefano Zampini if (!restore) { 2251dd7afcfSStefano Zampini Mat A_IB,A_BI; 226a3df083aSStefano Zampini PetscScalar *work; 227df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs->reuse_solver; 228a3df083aSStefano Zampini 2291dd7afcfSStefano Zampini if (pcbddc->benign_original_mat) { 2301dd7afcfSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 2311dd7afcfSStefano Zampini } 2321dd7afcfSStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) { 2331dd7afcfSStefano Zampini PetscFunctionReturn(0); 2341dd7afcfSStefano Zampini } 235a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 236a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 237a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 238a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 239a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 240a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 241a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 242a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 243a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 244a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 245a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 246a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 247059032f7SStefano Zampini if (reuse) { 248a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 2491dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 250059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 251059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 252059032f7SStefano Zampini PetscInt i; 253059032f7SStefano Zampini 254059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 255059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 256059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 257059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 258059032f7SStefano Zampini } 259059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 2601dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 261059032f7SStefano Zampini } 262a3df083aSStefano Zampini ctx->A = pcis->A_IB; 263a3df083aSStefano Zampini ctx->work = work; 264a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 265a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 266a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 267a3df083aSStefano Zampini pcis->A_IB = A_IB; 268a3df083aSStefano Zampini 269a3df083aSStefano Zampini /* A_BI as A_IB^T */ 270a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 271a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 272a3df083aSStefano Zampini pcis->A_BI = A_BI; 273a3df083aSStefano Zampini } else { 2741dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 2751dd7afcfSStefano Zampini PetscFunctionReturn(0); 2761dd7afcfSStefano Zampini } 277a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 278a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 279a3df083aSStefano Zampini pcis->A_IB = ctx->A; 2801dd7afcfSStefano Zampini ctx->A = NULL; 2811dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 2821dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 2831dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 2841dd7afcfSStefano Zampini if (ctx->free) { 285059032f7SStefano Zampini PetscInt i; 2861dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 287059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 288059032f7SStefano Zampini } 289059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 290059032f7SStefano Zampini } 291a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 292a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 293a3df083aSStefano Zampini } 294a3df083aSStefano Zampini PetscFunctionReturn(0); 295a3df083aSStefano Zampini } 296a3df083aSStefano Zampini 297a3df083aSStefano Zampini /* used just in bddc debug mode */ 298a3df083aSStefano Zampini #undef __FUNCT__ 299a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 300a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 301a3df083aSStefano Zampini { 302a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 303a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 304a3df083aSStefano Zampini Mat An; 305a3df083aSStefano Zampini PetscErrorCode ierr; 306a3df083aSStefano Zampini 307a3df083aSStefano Zampini PetscFunctionBegin; 308a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 309a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 310a3df083aSStefano Zampini if (is1) { 311a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 312a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 313a3df083aSStefano Zampini } else { 314a3df083aSStefano Zampini *B = An; 315a3df083aSStefano Zampini } 316a3df083aSStefano Zampini PetscFunctionReturn(0); 317a3df083aSStefano Zampini } 318a3df083aSStefano Zampini 3191cf9b237SStefano Zampini /* TODO: add reuse flag */ 3201cf9b237SStefano Zampini #undef __FUNCT__ 3211cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 3221cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 3231cf9b237SStefano Zampini { 3241cf9b237SStefano Zampini Mat Bt; 3251cf9b237SStefano Zampini PetscScalar *a,*bdata; 3261cf9b237SStefano Zampini const PetscInt *ii,*ij; 3271cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 3281cf9b237SStefano Zampini PetscBool flg_row; 3291cf9b237SStefano Zampini PetscErrorCode ierr; 3301cf9b237SStefano Zampini 3311cf9b237SStefano Zampini PetscFunctionBegin; 3321cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 3331cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 3341cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 3351cf9b237SStefano Zampini nnz = n; 3361cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 3371cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 3381cf9b237SStefano Zampini } 3391cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 3401cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 3411cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 3421cf9b237SStefano Zampini nnz = 0; 3431cf9b237SStefano Zampini bii[0] = 0; 3441cf9b237SStefano Zampini for (i=0;i<n;i++) { 3451cf9b237SStefano Zampini PetscInt j; 3461cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 3471cf9b237SStefano Zampini PetscScalar entry = a[j]; 3481cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 3491cf9b237SStefano Zampini bij[nnz] = ij[j]; 3501cf9b237SStefano Zampini bdata[nnz] = entry; 3511cf9b237SStefano Zampini nnz++; 3521cf9b237SStefano Zampini } 3531cf9b237SStefano Zampini } 3541cf9b237SStefano Zampini bii[i+1] = nnz; 3551cf9b237SStefano Zampini } 3561cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 3571cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 3581cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 3591cf9b237SStefano Zampini { 3601cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 3611cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 3621cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 3631cf9b237SStefano Zampini } 3641cf9b237SStefano Zampini *B = Bt; 3651cf9b237SStefano Zampini PetscFunctionReturn(0); 3661cf9b237SStefano Zampini } 3671cf9b237SStefano Zampini 368674ae819SStefano Zampini #undef __FUNCT__ 3694f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 3704f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 3714f1b2e48SStefano Zampini { 3724f1b2e48SStefano Zampini Mat B; 3734f1b2e48SStefano Zampini IS is_dummy,*cc_n; 3744f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 3754f1b2e48SStefano Zampini PCBDDCGraph graph; 3764f1b2e48SStefano Zampini PetscInt i,n; 3774f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 3784f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 3794f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 3804f1b2e48SStefano Zampini PetscErrorCode ierr; 3814f1b2e48SStefano Zampini 3824f1b2e48SStefano Zampini PetscFunctionBegin; 38363c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 38463c961adSStefano Zampini *ncc = 0; 38563c961adSStefano Zampini *cc = NULL; 38663c961adSStefano Zampini PetscFunctionReturn(0); 38763c961adSStefano Zampini } 3884f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 3894f1b2e48SStefano Zampini if (!isseqaij && filter) { 3901cf9b237SStefano Zampini PetscBool isseqdense; 3911cf9b237SStefano Zampini 3921cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 3931cf9b237SStefano Zampini if (!isseqdense) { 3944f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 3951cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 3961cf9b237SStefano Zampini PetscScalar *array; 3971cf9b237SStefano Zampini PetscReal chop=1.e-6; 3981cf9b237SStefano Zampini 3991cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 4001cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 4011cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 4021cf9b237SStefano Zampini for (i=0;i<n;i++) { 4031cf9b237SStefano Zampini PetscInt j; 4041cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 4051cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 4061cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 4071cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 4081cf9b237SStefano Zampini } 4091cf9b237SStefano Zampini } 4101cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 4119d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 4121cf9b237SStefano Zampini } 4134f1b2e48SStefano Zampini } else { 4144f1b2e48SStefano Zampini B = A; 4154f1b2e48SStefano Zampini } 4164f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4174f1b2e48SStefano Zampini 4184f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 4194f1b2e48SStefano Zampini if (filter) { 4204f1b2e48SStefano Zampini PetscScalar *data; 4214f1b2e48SStefano Zampini PetscInt j,cum; 4224f1b2e48SStefano Zampini 4234f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 4244f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 4254f1b2e48SStefano Zampini cum = 0; 4264f1b2e48SStefano Zampini for (i=0;i<n;i++) { 4274f1b2e48SStefano Zampini PetscInt t; 4284f1b2e48SStefano Zampini 4294f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 4304f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 4314f1b2e48SStefano Zampini continue; 4324f1b2e48SStefano Zampini } 4334f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 4344f1b2e48SStefano Zampini } 4354f1b2e48SStefano Zampini t = xadj_filtered[i]; 4364f1b2e48SStefano Zampini xadj_filtered[i] = cum; 4374f1b2e48SStefano Zampini cum += t; 4384f1b2e48SStefano Zampini } 4394f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 4404f1b2e48SStefano Zampini } else { 4414f1b2e48SStefano Zampini xadj_filtered = NULL; 4424f1b2e48SStefano Zampini adjncy_filtered = NULL; 4434f1b2e48SStefano Zampini } 4444f1b2e48SStefano Zampini 4454f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 4464f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 4474f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 4484f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4494f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 4504f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 4514f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 4524f1b2e48SStefano Zampini if (xadj_filtered) { 4534f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 4544f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 4554f1b2e48SStefano Zampini } else { 4564f1b2e48SStefano Zampini graph->xadj = xadj; 4574f1b2e48SStefano Zampini graph->adjncy = adjncy; 4584f1b2e48SStefano Zampini } 4594f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 4604f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 4614f1b2e48SStefano Zampini /* partial clean up */ 4624f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 4634f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4641cf9b237SStefano Zampini if (A != B) { 4654f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4664f1b2e48SStefano Zampini } 4674f1b2e48SStefano Zampini 4684f1b2e48SStefano Zampini /* get back data */ 4691cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 4701cf9b237SStefano Zampini if (cc) { 4714f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 4724f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 4734f1b2e48SStefano 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); 4744f1b2e48SStefano Zampini } 4754f1b2e48SStefano Zampini *cc = cc_n; 4761cf9b237SStefano Zampini } 4774f1b2e48SStefano Zampini /* clean up graph */ 4784f1b2e48SStefano Zampini graph->xadj = 0; 4794f1b2e48SStefano Zampini graph->adjncy = 0; 4804f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 4814f1b2e48SStefano Zampini PetscFunctionReturn(0); 4824f1b2e48SStefano Zampini } 4834f1b2e48SStefano Zampini 4844f1b2e48SStefano Zampini #undef __FUNCT__ 4855408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 4865408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 4875408967cSStefano Zampini { 4885408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4895408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 490dee84bffSStefano Zampini IS dirIS = NULL; 4914f1b2e48SStefano Zampini PetscInt i; 4925408967cSStefano Zampini PetscErrorCode ierr; 4935408967cSStefano Zampini 4945408967cSStefano Zampini PetscFunctionBegin; 495dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 4965408967cSStefano Zampini if (zerodiag) { 4975408967cSStefano Zampini Mat A; 4985408967cSStefano Zampini Vec vec3_N; 4995408967cSStefano Zampini PetscScalar *vals; 5005408967cSStefano Zampini const PetscInt *idxs; 501d12d3064SStefano Zampini PetscInt nz,*count; 5025408967cSStefano Zampini 5035408967cSStefano Zampini /* p0 */ 5045408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 5055408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 5065408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5075408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 5084f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 5095408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 5105408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5115408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5125408967cSStefano Zampini /* v_I */ 5135408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 5145408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 5155408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 5165408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 5175408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 5185408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 5195408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 5205408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 5215408967cSStefano Zampini if (dirIS) { 5225408967cSStefano Zampini PetscInt n; 5235408967cSStefano Zampini 5245408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 5255408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 5265408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 5275408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 5285408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 5295408967cSStefano Zampini } 5305408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 5315408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 5325408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 5335408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 5345408967cSStefano Zampini ierr = MatISGetLocalMat(pc->mat,&A);CHKERRQ(ierr); 5355408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 5365408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 537fbfcb133SStefano Zampini if (PetscAbsScalar(vals[0]) > 1.e-1) { 538b9b0e38cSStefano 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])); 5395408967cSStefano Zampini } 5405408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5415408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 542d12d3064SStefano Zampini 543d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 544d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 545d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 546d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 547d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 548d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 549d4d8cf7bSStefano Zampini for (i=0;i<nz;i++) { 550d12d3064SStefano Zampini if (count[idxs[i]]) { 551d12d3064SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 552d12d3064SStefano Zampini } 553d4d8cf7bSStefano Zampini } 554d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 555d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 5565408967cSStefano Zampini } 557dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 5585408967cSStefano Zampini 5595408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 5605408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 5614f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 5625408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 5634f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 5645408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 5654f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 5664f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 5674f1b2e48SStefano 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); 5684f1b2e48SStefano Zampini } 5695408967cSStefano Zampini } 5705408967cSStefano Zampini PetscFunctionReturn(0); 5715408967cSStefano Zampini } 5725408967cSStefano Zampini 5735408967cSStefano Zampini #undef __FUNCT__ 574339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 575339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 576339f8db1SStefano Zampini { 577339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5784f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 579b0f5fe93SStefano Zampini PetscInt nz,n; 5801f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 5814f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 582339f8db1SStefano Zampini PetscErrorCode ierr; 583339f8db1SStefano Zampini 584339f8db1SStefano Zampini PetscFunctionBegin; 5859f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 5869f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 587a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 588a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 589a3df083aSStefano Zampini } 590a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 591a3df083aSStefano Zampini pcbddc->benign_n = 0; 5924f1b2e48SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures" 5934f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 5944f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 5954f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 5964f1b2e48SStefano Zampini since the local Schur complements are SPD 5974f1b2e48SStefano Zampini */ 5984f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 5994f1b2e48SStefano Zampini have_null = PETSC_TRUE; 60040fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 6014f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 6024f1b2e48SStefano Zampini 6034f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 6044f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 6054f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 6064f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 607ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 60840fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 60940fa8d13SStefano Zampini if (!sorted) { 61040fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 61140fa8d13SStefano Zampini } 61240fa8d13SStefano Zampini } else { 61340fa8d13SStefano Zampini pressures = NULL; 61440fa8d13SStefano Zampini } 61597d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 61697d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 61727b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 61897d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 619339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 620339f8db1SStefano Zampini if (!sorted) { 621339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 622339f8db1SStefano Zampini } 623339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 6244f1b2e48SStefano Zampini if (!nz) { 6254f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 6264f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 62740fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 62840fa8d13SStefano Zampini } 6294f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 6304f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 6314f1b2e48SStefano Zampini zerodiag_subs = NULL; 6324f1b2e48SStefano Zampini pcbddc->benign_n = 0; 6331f4df5f7SStefano Zampini n_interior_dofs = 0; 6341f4df5f7SStefano Zampini interior_dofs = NULL; 6351f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 6361f4df5f7SStefano Zampini PetscInt n,i,j; 6371f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 6381f4df5f7SStefano Zampini PetscInt *iwork; 6391f4df5f7SStefano Zampini 6401f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 6411f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6421f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 6431f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 6441f4df5f7SStefano Zampini for (i=0;i<n_neigh;i++) 6451f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 6461f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 6471f4df5f7SStefano Zampini for (i=0;i<n;i++) 6481f4df5f7SStefano Zampini if (!iwork[i]) 6491f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 6501f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 6511f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6521f4df5f7SStefano Zampini } 6534f1b2e48SStefano Zampini if (has_null_pressures) { 6544f1b2e48SStefano Zampini IS *subs; 6551f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 6561f4df5f7SStefano Zampini const PetscInt *idxs; 6571f4df5f7SStefano Zampini PetscScalar *array; 6581f4df5f7SStefano Zampini Vec *work; 6591f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 6604f1b2e48SStefano Zampini 6614f1b2e48SStefano Zampini subs = pcbddc->local_subs; 6624f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 6631f4df5f7SStefano 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) */ 6641f4df5f7SStefano Zampini if (pcbddc->current_level) { 6651f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 6661f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 6671f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 6681f4df5f7SStefano Zampini /* work[0] = 1_p */ 6691f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 6701f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 6711f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 6721f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 6731f4df5f7SStefano Zampini /* work[0] = 1_v */ 6741f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 6751f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 6761f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 6771f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 6781f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 6791f4df5f7SStefano Zampini } 6804f1b2e48SStefano Zampini if (nsubs > 1) { 6814f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 6824f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 6834f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 6844f1b2e48SStefano Zampini IS t_zerodiag_subs; 6854f1b2e48SStefano Zampini PetscInt nl; 6864f1b2e48SStefano Zampini 6874f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 6884f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 6894f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 6904f1b2e48SStefano Zampini if (nl) { 6914f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 6924f1b2e48SStefano Zampini 6931f4df5f7SStefano Zampini if (pcbddc->current_level) { 6941f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 6951f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 6961f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 6971f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 6981f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 6991f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 7001f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 7011f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 7021f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 7031f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 7041f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 7051f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 7061f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 7071f4df5f7SStefano Zampini valid = PETSC_FALSE; 7081f4df5f7SStefano Zampini break; 7091f4df5f7SStefano Zampini } 7101f4df5f7SStefano Zampini } 7111f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 7121f4df5f7SStefano Zampini } 7131f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 7141f4df5f7SStefano Zampini IS t_bc; 7151f4df5f7SStefano Zampini PetscInt nzb; 7161f4df5f7SStefano Zampini 7171f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 7181f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 7191f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 7201f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 7211f4df5f7SStefano Zampini } 7221f4df5f7SStefano Zampini if (valid && pressures) { 7234f1b2e48SStefano Zampini IS t_pressure_subs; 7244f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 7254f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 7264f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 7274f1b2e48SStefano Zampini } 7284f1b2e48SStefano Zampini if (valid) { 7294f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 7304f1b2e48SStefano Zampini pcbddc->benign_n++; 7314f1b2e48SStefano Zampini } else { 7324f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 7334f1b2e48SStefano Zampini } 7344f1b2e48SStefano Zampini } 7354f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 7364f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 7374f1b2e48SStefano Zampini } 7384f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 7394f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 7401f4df5f7SStefano Zampini 7411f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 7421f4df5f7SStefano Zampini PetscInt nzb; 7431f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 7441f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 7451f4df5f7SStefano Zampini } 7461f4df5f7SStefano Zampini if (valid && pressures) { 7474f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 7484f1b2e48SStefano Zampini } 7491f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 7501f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 7511f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 7521f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 7531f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 7541f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 7551f4df5f7SStefano Zampini valid = PETSC_FALSE; 7561f4df5f7SStefano Zampini break; 7571f4df5f7SStefano Zampini } 7581f4df5f7SStefano Zampini } 7591f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 7601f4df5f7SStefano Zampini } 7614f1b2e48SStefano Zampini if (valid) { 7624f1b2e48SStefano Zampini pcbddc->benign_n = 1; 763ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 7644f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 7654f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 7664f1b2e48SStefano Zampini } 7674f1b2e48SStefano Zampini } 7681f4df5f7SStefano Zampini if (pcbddc->current_level) { 7691f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 7704f1b2e48SStefano Zampini } 7711f4df5f7SStefano Zampini } 7721f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 7734f1b2e48SStefano Zampini 7744f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 775b9b0e38cSStefano Zampini PetscInt n; 776b9b0e38cSStefano Zampini 7774f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 7784f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 779b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 780b9b0e38cSStefano Zampini if (n) { 7814f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 7824f1b2e48SStefano Zampini have_null = PETSC_FALSE; 7834f1b2e48SStefano Zampini } 784b9b0e38cSStefano Zampini } 7854f1b2e48SStefano Zampini 7864f1b2e48SStefano Zampini /* final check for null pressures */ 7874f1b2e48SStefano Zampini if (zerodiag && pressures) { 7884f1b2e48SStefano Zampini PetscInt nz,np; 7894f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 7904f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 7914f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 7924f1b2e48SStefano Zampini } 7934f1b2e48SStefano Zampini 7944f1b2e48SStefano Zampini if (recompute_zerodiag) { 7954f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 7964f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 7974f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 7984f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 7994f1b2e48SStefano Zampini } else { 8004f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 8014f1b2e48SStefano Zampini 8024f1b2e48SStefano Zampini nzn = 0; 8034f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 8044f1b2e48SStefano Zampini PetscInt ns; 8054f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 8064f1b2e48SStefano Zampini nzn += ns; 8074f1b2e48SStefano Zampini } 8084f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 8094f1b2e48SStefano Zampini nzn = 0; 8104f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 8114f1b2e48SStefano Zampini PetscInt ns,*idxs; 8124f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 8134f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 8144f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 8154f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 8164f1b2e48SStefano Zampini nzn += ns; 8174f1b2e48SStefano Zampini } 8184f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 8194f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 8204f1b2e48SStefano Zampini } 8214f1b2e48SStefano Zampini have_null = PETSC_FALSE; 8224f1b2e48SStefano Zampini } 8234f1b2e48SStefano Zampini 824b3afcdbeSStefano Zampini /* no-net-flux */ 825b3afcdbeSStefano Zampini if (pcbddc->benign_compute_nonetflux) { 826b3afcdbeSStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 827b3afcdbeSStefano Zampini MatNullSpace near_null_space; 828b3afcdbeSStefano Zampini ISLocalToGlobalMapping rmap; 829b3afcdbeSStefano Zampini Vec quad_vec; 830b3afcdbeSStefano Zampini PetscScalar *pvals; 831b3afcdbeSStefano Zampini PetscInt i,np,*dummyins; 8321f4df5f7SStefano Zampini IS isused = NULL; 8331f4df5f7SStefano Zampini PetscBool participate = PETSC_TRUE; 834b3afcdbeSStefano Zampini 835b3afcdbeSStefano Zampini /* create vector to hold quadrature weights */ 836b3afcdbeSStefano Zampini ierr = MatCreateVecs(pc->pmat,&quad_vec,NULL);CHKERRQ(ierr); 837b3afcdbeSStefano Zampini ierr = VecSet(quad_vec,0.0);CHKERRQ(ierr); 838b3afcdbeSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&rmap,NULL);CHKERRQ(ierr); 839b3afcdbeSStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vec,rmap);CHKERRQ(ierr); 840b3afcdbeSStefano Zampini 841b3afcdbeSStefano Zampini /* compute B^{(i)T} * 1_p */ 842b3afcdbeSStefano Zampini np = 0; 8431f4df5f7SStefano Zampini if (pressures) { 8441f4df5f7SStefano Zampini isused = pressures; 8451f4df5f7SStefano Zampini } else { 8461f4df5f7SStefano Zampini isused = zerodiag; 8471f4df5f7SStefano Zampini } 8481f4df5f7SStefano Zampini if (isused) { 8491f4df5f7SStefano Zampini ierr = ISGetLocalSize(isused,&np);CHKERRQ(ierr); 850b3afcdbeSStefano Zampini } 851b3afcdbeSStefano Zampini ierr = PetscMalloc1(np,&pvals);CHKERRQ(ierr); 852b3afcdbeSStefano Zampini for (i=0;i<np;i++) pvals[i] = 1.; 853b3afcdbeSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 854b3afcdbeSStefano Zampini if (np) { 855b3afcdbeSStefano Zampini const PetscInt *pidxs; 856b3afcdbeSStefano Zampini 8571f4df5f7SStefano Zampini if (isused) { 8581f4df5f7SStefano Zampini ierr = ISGetIndices(isused,&pidxs);CHKERRQ(ierr); 859b3afcdbeSStefano Zampini } 860b3afcdbeSStefano Zampini ierr = VecSetValues(matis->x,np,pidxs,pvals,INSERT_VALUES);CHKERRQ(ierr); 8611f4df5f7SStefano Zampini if (isused) { 8621f4df5f7SStefano Zampini ierr = ISRestoreIndices(isused,&pidxs);CHKERRQ(ierr); 863b3afcdbeSStefano Zampini } 864b3afcdbeSStefano Zampini } 865b3afcdbeSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 866b3afcdbeSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 867b3afcdbeSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 868b3afcdbeSStefano Zampini ierr = PetscFree(pvals);CHKERRQ(ierr); 8691f4df5f7SStefano Zampini if (!isused) participate = PETSC_FALSE; 870b3afcdbeSStefano Zampini /* decide which of the sharing ranks (per dof) has to insert the values (should just be a matter of having a different orientation) */ 871b3afcdbeSStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 872daf8a457SStefano Zampini for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = -1; 8731f4df5f7SStefano Zampini for (i=0;i<matis->sf->nleaves;i++) 8741f4df5f7SStefano Zampini if (participate) matis->sf_leafdata[i] = PetscGlobalRank; 8751f4df5f7SStefano Zampini else matis->sf_leafdata[i] = -1; 8761f4df5f7SStefano Zampini 877b3afcdbeSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_MAX);CHKERRQ(ierr); 878b3afcdbeSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_MAX);CHKERRQ(ierr); 879b3afcdbeSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 880b3afcdbeSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 881b3afcdbeSStefano Zampini ierr = VecGetArray(matis->y,&pvals);CHKERRQ(ierr); 882daf8a457SStefano Zampini for (i=0;i<matis->sf->nleaves;i++) { 883b3afcdbeSStefano Zampini if (PetscGlobalRank != matis->sf_leafdata[i]) { 884b3afcdbeSStefano Zampini pvals[i] = 0.; 885b3afcdbeSStefano Zampini } 886b3afcdbeSStefano Zampini } 887daf8a457SStefano Zampini ierr = PetscMalloc1(matis->sf->nleaves,&dummyins);CHKERRQ(ierr); 888daf8a457SStefano Zampini for (i=0;i<matis->sf->nleaves;i++) dummyins[i] = i; 889daf8a457SStefano Zampini ierr = VecSetValuesLocal(quad_vec,matis->sf->nleaves,dummyins,pvals,ADD_VALUES);CHKERRQ(ierr); 890b3afcdbeSStefano Zampini ierr = VecRestoreArray(matis->y,&pvals);CHKERRQ(ierr); 891b3afcdbeSStefano Zampini ierr = PetscFree(dummyins);CHKERRQ(ierr); 892b3afcdbeSStefano Zampini 893b3afcdbeSStefano Zampini /* assembly quadrature vec and attach near null space to pmat */ 894b3afcdbeSStefano Zampini ierr = VecAssemblyBegin(quad_vec);CHKERRQ(ierr); 895b3afcdbeSStefano Zampini ierr = VecAssemblyEnd(quad_vec);CHKERRQ(ierr); 896b3afcdbeSStefano Zampini ierr = VecNormalize(quad_vec,NULL);CHKERRQ(ierr); 897b3afcdbeSStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)pc),PETSC_FALSE,1,&quad_vec,&near_null_space);CHKERRQ(ierr); 898b3afcdbeSStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 899b3afcdbeSStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,near_null_space);CHKERRQ(ierr); 900b3afcdbeSStefano Zampini ierr = MatNullSpaceDestroy(&near_null_space);CHKERRQ(ierr); 901b3afcdbeSStefano Zampini } 902b3afcdbeSStefano Zampini 903b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 9044f1b2e48SStefano Zampini if (has_null_pressures) { 9054f1b2e48SStefano Zampini IS zerodiagc; 9064f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 9074f1b2e48SStefano Zampini PetscInt i,s,*nnz; 9084f1b2e48SStefano Zampini 9094f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 910339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 911339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 912339f8db1SStefano Zampini /* local change of basis for pressures */ 913339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 91497d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 915339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 916339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 917339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 9184f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 9194f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 9204f1b2e48SStefano Zampini PetscInt nzs,j; 9214f1b2e48SStefano Zampini 9224f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 9234f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 9244f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 9254f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 9264f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 9274f1b2e48SStefano Zampini } 928339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 929339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 930339f8db1SStefano Zampini /* set identity on velocities */ 931339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 932339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 933339f8db1SStefano Zampini } 9344f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 9354f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 9369f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 9374f1b2e48SStefano 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); 938339f8db1SStefano Zampini /* set change on pressures */ 9394f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 9404f1b2e48SStefano Zampini PetscScalar *array; 9414f1b2e48SStefano Zampini PetscInt nzs; 9424f1b2e48SStefano Zampini 9434f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 9444f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 9454f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 946339f8db1SStefano Zampini PetscScalar vals[2]; 947339f8db1SStefano Zampini PetscInt cols[2]; 948339f8db1SStefano Zampini 949339f8db1SStefano Zampini cols[0] = idxs[i]; 9504f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 951339f8db1SStefano Zampini vals[0] = 1.; 952b0f5fe93SStefano Zampini vals[1] = 1.; 9534f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 954339f8db1SStefano Zampini } 9554f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 9564f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 9574f1b2e48SStefano Zampini array[nzs-1] = 1.; 9584f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 9594f1b2e48SStefano Zampini /* store local idxs for p0 */ 9604f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 9614f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 962339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 9634f1b2e48SStefano Zampini } 964339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 965339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 966a3df083aSStefano Zampini /* project if needed */ 967a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 9681dd7afcfSStefano Zampini Mat M; 9691dd7afcfSStefano Zampini 9701dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 971339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 9721dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 9731dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 974a3df083aSStefano Zampini } 9754f1b2e48SStefano Zampini /* store global idxs for p0 */ 9764f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 977339f8db1SStefano Zampini } 978ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 9794f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 980b0f5fe93SStefano Zampini 981b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 982b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 98327b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 98427b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 985339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 986339f8db1SStefano Zampini PetscFunctionReturn(0); 987339f8db1SStefano Zampini } 988339f8db1SStefano Zampini 989339f8db1SStefano Zampini #undef __FUNCT__ 990015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 991015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 992efc2fbd9SStefano Zampini { 993efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 994de9d7bd0SStefano Zampini PetscScalar *array; 995efc2fbd9SStefano Zampini PetscErrorCode ierr; 996efc2fbd9SStefano Zampini 997efc2fbd9SStefano Zampini PetscFunctionBegin; 998efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 999efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 10004f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1001efc2fbd9SStefano Zampini } 1002de9d7bd0SStefano Zampini if (get) { 1003efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 10044f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 10054f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 1006efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 1007de9d7bd0SStefano Zampini } else { 1008de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 1009de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1010de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1011de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 1012efc2fbd9SStefano Zampini } 1013efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1014efc2fbd9SStefano Zampini } 1015efc2fbd9SStefano Zampini 1016efc2fbd9SStefano Zampini #undef __FUNCT__ 1017c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 1018c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 1019c263805aSStefano Zampini { 1020c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1021c263805aSStefano Zampini PetscErrorCode ierr; 1022c263805aSStefano Zampini 1023c263805aSStefano Zampini PetscFunctionBegin; 1024c263805aSStefano Zampini /* TODO: add error checking 1025c263805aSStefano Zampini - avoid nested pop (or push) calls. 1026c263805aSStefano Zampini - cannot push before pop. 10271c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 1028c263805aSStefano Zampini */ 10294f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1030efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1031efc2fbd9SStefano Zampini } 1032c263805aSStefano Zampini if (pop) { 1033a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 10344f1b2e48SStefano Zampini IS is_p0; 10354f1b2e48SStefano Zampini MatReuse reuse; 1036c263805aSStefano Zampini 1037c263805aSStefano Zampini /* extract B_0 */ 10384f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 10394f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 10404f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 10414f1b2e48SStefano Zampini } 10424f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 10434f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 1044c263805aSStefano Zampini /* remove rows and cols from local problem */ 1045c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 104697d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 10474f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 10484f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 1049a3df083aSStefano Zampini } else { 1050a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1051a3df083aSStefano Zampini PetscScalar *vals; 1052a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 1053a3df083aSStefano Zampini 1054a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 1055a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 1056a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 10570b5adadeSStefano Zampini PetscInt *nnz; 1058a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 1059a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 1060a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1061331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 1062331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1063331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 1064331e053bSStefano Zampini nnz[i] = n - nnz[i]; 1065331e053bSStefano Zampini } 1066331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 1067331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1068331e053bSStefano Zampini } 1069a3df083aSStefano Zampini 1070a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1071a3df083aSStefano Zampini PetscScalar *array; 1072a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 1073a3df083aSStefano Zampini 1074a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 1075a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1076a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1077a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 1078a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1079a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 1080a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 1081a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 1082a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 1083a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 1084a3df083aSStefano Zampini cum = 0; 1085a3df083aSStefano Zampini for (j=0;j<n;j++) { 108622db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 1087a3df083aSStefano Zampini vals[cum] = array[j]; 1088a3df083aSStefano Zampini idxs_ins[cum] = j; 1089a3df083aSStefano Zampini cum++; 1090a3df083aSStefano Zampini } 1091a3df083aSStefano Zampini } 1092a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 1093a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 1094a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 1095a3df083aSStefano Zampini } 1096a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1097a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1098a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 1099a3df083aSStefano Zampini } 1100c263805aSStefano Zampini } else { /* push */ 1101a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 11024f1b2e48SStefano Zampini PetscInt i; 11034f1b2e48SStefano Zampini 11044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 11054f1b2e48SStefano Zampini PetscScalar *B0_vals; 11064f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 11074f1b2e48SStefano Zampini 11084f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 11094f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 11107b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 11114f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 11124f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 11134f1b2e48SStefano Zampini } 1114c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1115c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1116a3df083aSStefano Zampini } else { 1117a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 1118a3df083aSStefano Zampini } 1119c263805aSStefano Zampini } 1120c263805aSStefano Zampini PetscFunctionReturn(0); 1121c263805aSStefano Zampini } 1122c263805aSStefano Zampini 1123c263805aSStefano Zampini #undef __FUNCT__ 1124b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 112508122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 1126b1b3d7a2SStefano Zampini { 1127b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 112808122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 112908122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 113008122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 113108122e43SStefano Zampini PetscScalar *work,lwork; 113208122e43SStefano Zampini PetscScalar *St,*S,*eigv; 113308122e43SStefano Zampini PetscScalar *Sarray,*Starray; 113408122e43SStefano Zampini PetscReal *eigs,thresh; 11351b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 1136f6f667cfSStefano Zampini PetscBool allocated_S_St; 113708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 113808122e43SStefano Zampini PetscReal *rwork; 113908122e43SStefano Zampini #endif 1140b1b3d7a2SStefano Zampini PetscErrorCode ierr; 1141b1b3d7a2SStefano Zampini 1142b1b3d7a2SStefano Zampini PetscFunctionBegin; 1143af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 1144af25d912SStefano 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); 114506a4e24aSStefano Zampini 1146fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1147fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1148fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1149fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 11501575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1151fd14bc51SStefano Zampini } 1152fd14bc51SStefano Zampini 1153e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 1154e496cd5dSStefano 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); 1155e496cd5dSStefano Zampini } 1156e496cd5dSStefano Zampini 115708122e43SStefano Zampini /* max size of subsets */ 115808122e43SStefano Zampini mss = 0; 115908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 116008122e43SStefano Zampini PetscInt subset_size; 1161862806e4SStefano Zampini 116208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 116308122e43SStefano Zampini mss = PetscMax(mss,subset_size); 116408122e43SStefano Zampini } 116508122e43SStefano Zampini 116608122e43SStefano Zampini /* min/max and threshold */ 116708122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 1168f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 116908122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 1170f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 1171f6f667cfSStefano Zampini if (nmin) { 1172f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 1173f6f667cfSStefano Zampini } 117408122e43SStefano Zampini 117508122e43SStefano Zampini /* allocate lapack workspace */ 117608122e43SStefano Zampini cum = cum2 = 0; 117708122e43SStefano Zampini maxneigs = 0; 117808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 117908122e43SStefano Zampini PetscInt n,subset_size; 1180f6f667cfSStefano Zampini 118108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 118208122e43SStefano Zampini n = PetscMin(subset_size,nmax); 11839162d606SStefano Zampini cum += subset_size; 11849162d606SStefano Zampini cum2 += subset_size*n; 118508122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 118608122e43SStefano Zampini } 118708122e43SStefano Zampini if (mss) { 11889ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 118908122e43SStefano Zampini PetscBLASInt B_itype = 1; 119008122e43SStefano Zampini PetscBLASInt B_N = mss; 11914c6709b3SStefano Zampini PetscReal zero = 0.0; 11924c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 119308122e43SStefano Zampini 119408122e43SStefano Zampini B_lwork = -1; 119508122e43SStefano Zampini S = NULL; 119608122e43SStefano Zampini St = NULL; 1197a58a30b4SStefano Zampini eigs = NULL; 1198a58a30b4SStefano Zampini eigv = NULL; 1199a58a30b4SStefano Zampini B_iwork = NULL; 1200a58a30b4SStefano Zampini B_ifail = NULL; 1201d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1202d1710679SStefano Zampini rwork = NULL; 1203d1710679SStefano Zampini #endif 12048bec7fa6SStefano Zampini thresh = 1.0; 120508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 120608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 120708122e43SStefano 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)); 120808122e43SStefano Zampini #else 120908122e43SStefano 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)); 121008122e43SStefano Zampini #endif 121108122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 121208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 121308122e43SStefano Zampini } else { 121408122e43SStefano Zampini /* TODO */ 121508122e43SStefano Zampini } 121608122e43SStefano Zampini } else { 121708122e43SStefano Zampini lwork = 0; 121808122e43SStefano Zampini } 121908122e43SStefano Zampini 122008122e43SStefano Zampini nv = 0; 1221d62866d3SStefano 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) */ 1222d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 122308122e43SStefano Zampini } 12244c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 1225f6f667cfSStefano Zampini if (allocated_S_St) { 1226f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 1227f6f667cfSStefano Zampini } 1228f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 122908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 123008122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 123108122e43SStefano Zampini #endif 12329162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 12339162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 12349162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 123508122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 12369162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 123708122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 123808122e43SStefano Zampini 123908122e43SStefano Zampini maxneigs = 0; 124072b8c272SStefano Zampini cum = cumarray = 0; 12419162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 12429162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 1243d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 124408122e43SStefano Zampini const PetscInt *idxs; 124508122e43SStefano Zampini 1246d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 124708122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 124808122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 124908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 125008122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 12519162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 12529162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 125308122e43SStefano Zampini } 1254d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 125508122e43SStefano Zampini } 125608122e43SStefano Zampini 125708122e43SStefano Zampini if (mss) { /* multilevel */ 125808122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 125908122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 126008122e43SStefano Zampini } 126108122e43SStefano Zampini 1262ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 126308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 126408122e43SStefano Zampini const PetscInt *idxs; 12659d54b7f4SStefano Zampini PetscReal upper,lower; 1266862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 126708122e43SStefano Zampini PetscBLASInt B_N; 1268aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 126908122e43SStefano Zampini 12709d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 12719d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 12729d54b7f4SStefano Zampini lower = thresh; 12739d54b7f4SStefano Zampini } else { 12749d54b7f4SStefano Zampini upper = 1./thresh; 12759d54b7f4SStefano Zampini lower = 0.; 12769d54b7f4SStefano Zampini } 1277862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 1278ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 1279f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 1280f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 12819ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 1282aff50787SStefano Zampini PetscInt j,k; 1283aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 1284aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 1285aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 128608122e43SStefano Zampini } 128708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 1288aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 1289aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 1290aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 1291aff50787SStefano Zampini } 129208122e43SStefano Zampini } 129308122e43SStefano Zampini } else { 129408122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 129508122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 129608122e43SStefano Zampini } 12978bec7fa6SStefano Zampini } else { 1298f6f667cfSStefano Zampini S = Sarray + cumarray; 1299f6f667cfSStefano Zampini St = Starray + cumarray; 13008bec7fa6SStefano Zampini } 1301aff50787SStefano Zampini /* see if we can save some work */ 1302b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 1303aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1304aff50787SStefano Zampini } 1305aff50787SStefano Zampini 1306b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 1307aff50787SStefano Zampini B_neigs = 0; 1308aff50787SStefano Zampini } else { 13099ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 131008122e43SStefano Zampini PetscBLASInt B_itype = 1; 1311f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 13124c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 13139552c7c7SStefano Zampini PetscInt nmin_s; 1314b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 131508122e43SStefano Zampini 1316fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 13178bec7fa6SStefano 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]]); 1318fd14bc51SStefano Zampini } 1319d16cbb6bSStefano Zampini 1320b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 1321b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 1322b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 1323b7ab4a40SStefano Zampini } 1324b7ab4a40SStefano Zampini 132508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1326b7ab4a40SStefano Zampini if (compute_range) { 1327d16cbb6bSStefano Zampini 1328d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 132908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 13309d54b7f4SStefano 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)); 133108122e43SStefano Zampini #else 13329d54b7f4SStefano 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)); 133308122e43SStefano Zampini #endif 1334b7ab4a40SStefano Zampini } else if (!same_data) { 1335d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1336d16cbb6bSStefano Zampini B_IL = 1; 1337d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 13389d54b7f4SStefano 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)); 1339d16cbb6bSStefano Zampini #else 13409d54b7f4SStefano 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)); 1341d16cbb6bSStefano Zampini #endif 1342b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 1343b7ab4a40SStefano Zampini PetscInt k; 1344b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 1345b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 1346b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 1347b7ab4a40SStefano Zampini nmin = nmax; 1348b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 1349b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 1350b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 1351b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 1352b7ab4a40SStefano Zampini } 1353d16cbb6bSStefano Zampini } 135408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 135508122e43SStefano Zampini if (B_ierr) { 13566c4ed002SBarry 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); 13576c4ed002SBarry 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); 13586c4ed002SBarry 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); 135908122e43SStefano Zampini } 136008122e43SStefano Zampini 136108122e43SStefano Zampini if (B_neigs > nmax) { 1362fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1363fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1364fd14bc51SStefano Zampini } 13659d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 136608122e43SStefano Zampini B_neigs = nmax; 136708122e43SStefano Zampini } 136808122e43SStefano Zampini 13699552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 13709552c7c7SStefano Zampini if (B_neigs < nmin_s) { 137108122e43SStefano Zampini PetscBLASInt B_neigs2; 137208122e43SStefano Zampini 13739d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1374f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 13759d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 13769d54b7f4SStefano Zampini } else { 13779d54b7f4SStefano Zampini B_IL = B_neigs + 1; 13789d54b7f4SStefano Zampini B_IU = nmin_s; 13799d54b7f4SStefano Zampini } 1380fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1381fd14bc51SStefano 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); 1382fd14bc51SStefano Zampini } 13839ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 138408122e43SStefano Zampini PetscInt j; 138508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 138608122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 138708122e43SStefano Zampini } 138808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 138908122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 139008122e43SStefano Zampini } 139108122e43SStefano Zampini } else { 139208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 139308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 139408122e43SStefano Zampini } 139508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 139608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 13979d54b7f4SStefano 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)); 139808122e43SStefano Zampini #else 13999d54b7f4SStefano 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)); 140008122e43SStefano Zampini #endif 140108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 140208122e43SStefano Zampini B_neigs += B_neigs2; 140308122e43SStefano Zampini } 140408122e43SStefano Zampini if (B_ierr) { 14056c4ed002SBarry 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); 14066c4ed002SBarry 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); 14076c4ed002SBarry 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); 140808122e43SStefano Zampini } 1409fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1410ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 141108122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 141208122e43SStefano Zampini if (eigs[j] == 0.0) { 1413ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 141408122e43SStefano Zampini } else { 14159d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1416ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 14179d54b7f4SStefano Zampini } else { 14189d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 14199d54b7f4SStefano Zampini } 1420fd14bc51SStefano Zampini } 142108122e43SStefano Zampini } 142208122e43SStefano Zampini } 142308122e43SStefano Zampini } else { 142408122e43SStefano Zampini /* TODO */ 142508122e43SStefano Zampini } 1426aff50787SStefano Zampini } 14276c3e6151SStefano Zampini /* change the basis back to the original one */ 14286c3e6151SStefano Zampini if (sub_schurs->change) { 142972b8c272SStefano Zampini Mat change,phi,phit; 14306c3e6151SStefano Zampini 14316c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 14326c3e6151SStefano Zampini PetscInt ii; 14336c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 14346c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 14356c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 14366c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 14376c3e6151SStefano Zampini } 14386c3e6151SStefano Zampini } 14396c3e6151SStefano Zampini } 144072b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 14416c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 144272b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 14436c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 14446c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 14456c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 14466c3e6151SStefano Zampini } 14478bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 14488bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 14499162d606SStefano Zampini if (B_neigs) { 14509162d606SStefano 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); 1451fd14bc51SStefano Zampini 1452fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 14539552c7c7SStefano Zampini PetscInt ii; 14549552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1455ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 14569552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1457ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1458ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1459ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1460ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1461ac47001eSStefano Zampini #else 1462ac47001eSStefano 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); 1463ac47001eSStefano Zampini #endif 14649552c7c7SStefano Zampini } 14659552c7c7SStefano Zampini } 1466fd14bc51SStefano Zampini } 14679162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 14689162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 14699162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 14709162d606SStefano Zampini cum++; 147108122e43SStefano Zampini } 147208122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 147308122e43SStefano Zampini /* shift for next computation */ 147408122e43SStefano Zampini cumarray += subset_size*subset_size; 147508122e43SStefano Zampini } 1476fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1477fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1478fd14bc51SStefano Zampini } 147908122e43SStefano Zampini 148008122e43SStefano Zampini if (mss) { 148108122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 148208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1483f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1484f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1485f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 148608122e43SStefano Zampini } 1487f6f667cfSStefano Zampini if (allocated_S_St) { 1488f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1489f6f667cfSStefano Zampini } 1490f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 149108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 149208122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 149308122e43SStefano Zampini #endif 149408122e43SStefano Zampini if (pcbddc->dbg_flag) { 14951b968477SStefano Zampini PetscInt maxneigs_r; 1496b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 14979b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 149808122e43SStefano Zampini } 149908122e43SStefano Zampini PetscFunctionReturn(0); 150008122e43SStefano Zampini } 1501b1b3d7a2SStefano Zampini 1502674ae819SStefano Zampini #undef __FUNCT__ 1503c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1504c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1505c8587f34SStefano Zampini { 15068629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1507c8587f34SStefano Zampini PetscErrorCode ierr; 1508c8587f34SStefano Zampini 1509c8587f34SStefano Zampini PetscFunctionBegin; 1510f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 15115e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1512c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1513c8587f34SStefano Zampini 1514684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 15150fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1516684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1517c8587f34SStefano Zampini 15188629588bSStefano Zampini /* 15198629588bSStefano Zampini Setup local correction and local part of coarse basis. 15208629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 15218629588bSStefano Zampini */ 152247f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 15238629588bSStefano Zampini 15248629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 15258629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 15268629588bSStefano Zampini 15278629588bSStefano Zampini /* free */ 15288629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1529c8587f34SStefano Zampini PetscFunctionReturn(0); 1530c8587f34SStefano Zampini } 1531c8587f34SStefano Zampini 1532c8587f34SStefano Zampini #undef __FUNCT__ 1533674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1534674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1535674ae819SStefano Zampini { 1536674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1537674ae819SStefano Zampini PetscErrorCode ierr; 1538674ae819SStefano Zampini 1539674ae819SStefano Zampini PetscFunctionBegin; 1540674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1541674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 154230368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1543674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1544785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1545674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1546f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1547f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1548785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 154963602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 155063602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1551674ae819SStefano Zampini PetscFunctionReturn(0); 1552674ae819SStefano Zampini } 1553674ae819SStefano Zampini 1554674ae819SStefano Zampini #undef __FUNCT__ 1555674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1556674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1557674ae819SStefano Zampini { 1558674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15594f1b2e48SStefano Zampini PetscInt i; 1560674ae819SStefano Zampini PetscErrorCode ierr; 1561674ae819SStefano Zampini 1562674ae819SStefano Zampini PetscFunctionBegin; 1563b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1564674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 156516909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 15661dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 1567674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1568674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 15694f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 15704f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 15714f1b2e48SStefano Zampini } 15724f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1573b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1574674ae819SStefano Zampini PetscFunctionReturn(0); 1575674ae819SStefano Zampini } 1576674ae819SStefano Zampini 1577674ae819SStefano Zampini #undef __FUNCT__ 1578674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1579674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1580674ae819SStefano Zampini { 1581674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1582674ae819SStefano Zampini PetscErrorCode ierr; 1583674ae819SStefano Zampini 1584674ae819SStefano Zampini PetscFunctionBegin; 1585674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 158658da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1587ca92afb2SStefano Zampini PetscScalar *array; 158806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 158906656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 159058da7f69SStefano Zampini } 1591674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1592674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 159315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 159415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1595674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1596674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1597674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 159806656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1599674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1600674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 16018ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1602674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1603674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1604674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1605f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1606f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1607f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1608f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1609727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 16100e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1611f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 161270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 161381d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 16140369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 16151dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 16164f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 16178b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1618ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1619ca92afb2SStefano Zampini PetscInt i; 1620ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1621ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1622ca92afb2SStefano Zampini } 1623ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1624ca92afb2SStefano Zampini } 16254f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1626674ae819SStefano Zampini PetscFunctionReturn(0); 1627674ae819SStefano Zampini } 1628674ae819SStefano Zampini 1629674ae819SStefano Zampini #undef __FUNCT__ 1630f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1631f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 16326bfb1811SStefano Zampini { 16336bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16346bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 16356bfb1811SStefano Zampini VecType impVecType; 16364f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 16376bfb1811SStefano Zampini PetscErrorCode ierr; 16386bfb1811SStefano Zampini 16396bfb1811SStefano Zampini PetscFunctionBegin; 16406c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1641e7b262bdSStefano Zampini /* get sizes */ 16424f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1643b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 16446bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1645e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1646e7b262bdSStefano Zampini /* R nodes */ 1647e7b262bdSStefano Zampini old_size = -1; 1648e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1649e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1650e7b262bdSStefano Zampini } 1651e7b262bdSStefano Zampini if (n_R != old_size) { 1652e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1653e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 16546bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 16556bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 16566bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 16576bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1658e7b262bdSStefano Zampini } 1659e7b262bdSStefano Zampini /* local primal dofs */ 1660e7b262bdSStefano Zampini old_size = -1; 1661e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1662e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1663e7b262bdSStefano Zampini } 1664e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1665e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 166683b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1667e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 16686bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1669e7b262bdSStefano Zampini } 1670e7b262bdSStefano Zampini /* local explicit constraints */ 1671e7b262bdSStefano Zampini old_size = -1; 1672e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1673e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1674e7b262bdSStefano Zampini } 1675e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1676e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 167783b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 167883b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 167983b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 168083b7ccabSStefano Zampini } 16816bfb1811SStefano Zampini PetscFunctionReturn(0); 16826bfb1811SStefano Zampini } 16836bfb1811SStefano Zampini 16846bfb1811SStefano Zampini #undef __FUNCT__ 168547f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 168647f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 168788ebb749SStefano Zampini { 168825084f0cSStefano Zampini PetscErrorCode ierr; 168925084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 169088ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 169188ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1692d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 169325084f0cSStefano Zampini /* submatrices of local problem */ 169480677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 169506656605SStefano Zampini /* submatrices of local coarse problem */ 169606656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 169725084f0cSStefano Zampini /* working matrices */ 169806656605SStefano Zampini Mat C_CR; 169925084f0cSStefano Zampini /* additional working stuff */ 170006656605SStefano Zampini PC pc_R; 17014f1b2e48SStefano Zampini Mat F; 17025cbda25cSStefano Zampini Vec dummy_vec; 1703a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 170425084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 170506656605SStefano Zampini PetscScalar *work; 170606656605SStefano Zampini PetscInt *idx_V_B; 1707ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 170806656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1709ffd830a3SStefano Zampini 171025084f0cSStefano Zampini /* some shortcuts to scalars */ 171106656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 171288ebb749SStefano Zampini 171388ebb749SStefano Zampini PetscFunctionBegin; 1714ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1715ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1716ffd830a3SStefano Zampini } 1717ffd830a3SStefano Zampini 1718ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1719b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 17204f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1721b371cd4fSStefano Zampini n_B = pcis->n_B; 1722b371cd4fSStefano Zampini n_D = pcis->n - n_B; 172388ebb749SStefano Zampini n_R = pcis->n - n_vertices; 172488ebb749SStefano Zampini 172588ebb749SStefano Zampini /* vertices in boundary numbering */ 1726785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 17270e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 17286c4ed002SBarry 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); 172988ebb749SStefano Zampini 173006656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1731019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 173206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 173306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 173406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 173506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 173606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 173706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 173806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 173906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 174006656605SStefano Zampini 174106656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 174206656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 174306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 174406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 174506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1746ffd830a3SStefano Zampini lda_rhs = n_R; 1747a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 174806656605SStefano Zampini if (isLU || isILU || isCHOL) { 174906656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1750df4d28bfSStefano Zampini } else if (sub_schurs->reuse_solver) { 1751df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1752d62866d3SStefano Zampini MatFactorType type; 1753d62866d3SStefano Zampini 1754df4d28bfSStefano Zampini F = reuse_solver->F; 17556816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1756d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1757ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 175822db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 175906656605SStefano Zampini } else { 176006656605SStefano Zampini F = NULL; 176106656605SStefano Zampini } 176206656605SStefano Zampini 1763ffd830a3SStefano Zampini /* allocate workspace */ 1764ffd830a3SStefano Zampini n = 0; 1765ffd830a3SStefano Zampini if (n_constraints) { 1766ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1767ffd830a3SStefano Zampini } 1768ffd830a3SStefano Zampini if (n_vertices) { 1769ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1770ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1771ffd830a3SStefano Zampini } 1772ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1773ffd830a3SStefano Zampini 17745cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 17755cbda25cSStefano Zampini dummy_vec = NULL; 17765cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 17775cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 17785cbda25cSStefano Zampini } 17795cbda25cSStefano Zampini 178088ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 178188ebb749SStefano Zampini if (n_constraints) { 178272b8c272SStefano Zampini Mat M1,M2,M3,C_B; 178306656605SStefano Zampini IS is_aux; 178480677318SStefano Zampini PetscScalar *array,*array2; 178506656605SStefano Zampini 1786f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 178780677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 178888ebb749SStefano Zampini 178925084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 179025084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 17918ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 179272b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 179388ebb749SStefano Zampini 179480677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 179580677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1796ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 179788ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 179806656605SStefano Zampini const PetscScalar *row_cmat_values; 179906656605SStefano Zampini const PetscInt *row_cmat_indices; 180006656605SStefano Zampini PetscInt size_of_constraint,j; 180188ebb749SStefano Zampini 180206656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 180306656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1804ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 180506656605SStefano Zampini } 180606656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 180706656605SStefano Zampini } 1808ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 180906656605SStefano Zampini if (F) { 181006656605SStefano Zampini Mat B; 181106656605SStefano Zampini 1812ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1813a3df083aSStefano Zampini if (need_benign_correction) { 1814df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1815a3df083aSStefano Zampini 181672b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 181772b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 1818a3df083aSStefano Zampini } 181980677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1820a3df083aSStefano Zampini if (need_benign_correction) { 1821a3df083aSStefano Zampini PetscScalar *marr; 1822df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1823a3df083aSStefano Zampini 1824a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 18255cbda25cSStefano Zampini if (lda_rhs != n_R) { 18265cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 18275cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 18285cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 18295cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 18305cbda25cSStefano Zampini } 18315cbda25cSStefano Zampini } else { 1832a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1833a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 18345cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 1835a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1836a3df083aSStefano Zampini } 18375cbda25cSStefano Zampini } 1838a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1839a3df083aSStefano Zampini } 184006656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 184106656605SStefano Zampini } else { 184280677318SStefano Zampini PetscScalar *marr; 184380677318SStefano Zampini 184480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 184506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1846ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1847ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 184806656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 184906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 185006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 185106656605SStefano Zampini } 185280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 185306656605SStefano Zampini } 185480677318SStefano Zampini if (!pcbddc->switch_static) { 185580677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 185680677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 185780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 185880677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1859ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 186080677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 186180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186380677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 186480677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 186580677318SStefano Zampini } 186680677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 186780677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 186872b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 186980677318SStefano Zampini } else { 1870ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1871ffd830a3SStefano Zampini IS dummy; 1872ffd830a3SStefano Zampini 1873ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 187472b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1875ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1876ffd830a3SStefano Zampini } else { 187780677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 187880677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1879ffd830a3SStefano Zampini } 188025084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 188180677318SStefano Zampini } 188280677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 188380677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 188480677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 188506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 188606656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 188780677318SStefano Zampini if (isCHOL) { 188880677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 188980677318SStefano Zampini } else { 189025084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 189180677318SStefano Zampini } 189280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 189306656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 189425084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 189525084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 189625084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 189780677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 189872b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 189972b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 190006656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 190106656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1902f4ddd8eeSStefano Zampini } 1903fc227af8SStefano Zampini 1904fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 190588ebb749SStefano Zampini if (n_vertices) { 190606656605SStefano Zampini IS is_aux; 19073a50541eSStefano Zampini 1908df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 19096816873aSStefano Zampini IS tis; 19106816873aSStefano Zampini 19116816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 19126816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 19136816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 19146816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 19156816873aSStefano Zampini } else { 19163a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 19176816873aSStefano Zampini } 19189577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 19199577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 192004708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 192125084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 192288ebb749SStefano Zampini } 192388ebb749SStefano Zampini 192488ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1925f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 192606656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 192706656605SStefano Zampini if (pcbddc->coarse_phi_D) { 192806656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 192906656605SStefano Zampini } 1930f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 193106656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 193206656605SStefano Zampini PetscScalar *marray; 193306656605SStefano Zampini 193406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 193506656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1936f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1937f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1938f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1939f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1940f4ddd8eeSStefano Zampini } 1941f4ddd8eeSStefano Zampini } 194206656605SStefano Zampini 1943f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 194406656605SStefano Zampini PetscScalar *marray; 194588ebb749SStefano Zampini 194606656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 19478eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 194806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 194988ebb749SStefano Zampini } 19503301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 195106656605SStefano Zampini n *= 2; 195288ebb749SStefano Zampini } 195306656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 195406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 195506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 19568eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 195706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 195806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 195988ebb749SStefano Zampini } 19603301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 196106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 19628eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 196306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 196406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 196588ebb749SStefano Zampini } 196688ebb749SStefano Zampini } else { 1967c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1968c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 19691b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1970c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1971c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1972c0553b1fSStefano Zampini } 197388ebb749SStefano Zampini } 197406656605SStefano Zampini } 1975019a44ceSStefano Zampini 197606656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 19774f1b2e48SStefano Zampini p0_lidx_I = NULL; 19784f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1979d12edf2fSStefano Zampini const PetscInt *idxs; 1980d12edf2fSStefano Zampini 1981d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 19824f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 19834f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 19844f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 19854f1b2e48SStefano Zampini } 1986d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1987d12edf2fSStefano Zampini } 1988d16cbb6bSStefano Zampini 198906656605SStefano Zampini /* vertices */ 199006656605SStefano Zampini if (n_vertices) { 199116f15bc4SStefano Zampini 1992af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 199304708bb6SStefano Zampini 199416f15bc4SStefano Zampini if (n_R) { 199514393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 199606656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 199716f15bc4SStefano Zampini PetscScalar *x,*y; 199804708bb6SStefano Zampini PetscBool isseqaij; 199906656605SStefano Zampini 200021eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 200114393ed6SStefano Zampini if (need_benign_correction) { 200214393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 200314393ed6SStefano Zampini IS is_p0; 200414393ed6SStefano Zampini PetscInt *idxs_p0,n; 200514393ed6SStefano Zampini 200614393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 200714393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 200814393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 2009af25d912SStefano 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); 201014393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 201114393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 201214393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 201314393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 201414393ed6SStefano Zampini } 201514393ed6SStefano Zampini 2016ffd830a3SStefano Zampini if (lda_rhs == n_R) { 2017af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2018ffd830a3SStefano Zampini } else { 2019ca92afb2SStefano Zampini PetscScalar *av,*array; 2020ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 2021ca92afb2SStefano Zampini PetscInt n; 2022ca92afb2SStefano Zampini PetscBool flg_row; 2023ffd830a3SStefano Zampini 2024ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 2025ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 20269d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2027ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2028ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 2029ca92afb2SStefano Zampini for (i=0;i<n;i++) { 2030ca92afb2SStefano Zampini PetscInt j; 2031ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 2032ffd830a3SStefano Zampini } 2033ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2034ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2035ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 2036ffd830a3SStefano Zampini } 2037ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2038a3df083aSStefano Zampini if (need_benign_correction) { 2039df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2040a3df083aSStefano Zampini PetscScalar *marr; 2041a3df083aSStefano Zampini 2042a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 204314393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 204414393ed6SStefano Zampini 204514393ed6SStefano Zampini | 0 0 0 | (V) 204614393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 204714393ed6SStefano Zampini | 0 0 -1 | (p0) 204814393ed6SStefano Zampini 204914393ed6SStefano Zampini */ 2050df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 205114393ed6SStefano Zampini const PetscScalar *vals; 205214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 205314393ed6SStefano Zampini PetscInt n,j,nz; 205414393ed6SStefano Zampini 2055df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2056df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 205714393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 205814393ed6SStefano Zampini for (j=0;j<n;j++) { 205914393ed6SStefano Zampini PetscScalar val = vals[j]; 206014393ed6SStefano Zampini PetscInt k,col = idxs[j]; 206114393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 206214393ed6SStefano Zampini } 206314393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2064df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 206514393ed6SStefano Zampini } 206672b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 206772b8c272SStefano Zampini } 206872b8c272SStefano Zampini if (F) { 206914393ed6SStefano Zampini /* need to correct the rhs */ 207072b8c272SStefano Zampini if (need_benign_correction) { 207172b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 207272b8c272SStefano Zampini PetscScalar *marr; 207372b8c272SStefano Zampini 207472b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 20755cbda25cSStefano Zampini if (lda_rhs != n_R) { 20765cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 20775cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 20785cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 20795cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 20805cbda25cSStefano Zampini } 20815cbda25cSStefano Zampini } else { 2082a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2083a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 20845cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2085a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2086a3df083aSStefano Zampini } 20875cbda25cSStefano Zampini } 2088a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 2089a3df083aSStefano Zampini } 209006656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 209114393ed6SStefano Zampini /* need to correct the solution */ 2092a3df083aSStefano Zampini if (need_benign_correction) { 2093df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2094a3df083aSStefano Zampini PetscScalar *marr; 2095a3df083aSStefano Zampini 2096a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 20975cbda25cSStefano Zampini if (lda_rhs != n_R) { 20985cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 20995cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 21005cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 21015cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 21025cbda25cSStefano Zampini } 21035cbda25cSStefano Zampini } else { 2104a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 2105a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 21065cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2107a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2108a3df083aSStefano Zampini } 21095cbda25cSStefano Zampini } 2110a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 2111a3df083aSStefano Zampini } 211206656605SStefano Zampini } else { 211306656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 211406656605SStefano Zampini for (i=0;i<n_vertices;i++) { 2115ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 2116ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 211706656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 211806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 211906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 212006656605SStefano Zampini } 212106656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 212206656605SStefano Zampini } 212380677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2124ffd830a3SStefano Zampini /* S_VV and S_CV */ 212506656605SStefano Zampini if (n_constraints) { 212606656605SStefano Zampini Mat B; 212780677318SStefano Zampini 2128ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 212980677318SStefano Zampini for (i=0;i<n_vertices;i++) { 2130ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 2131ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 213280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213480677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 213580677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 213680677318SStefano Zampini } 2137ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 213880677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 213980677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 2140ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 214180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 214206656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 2143ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 2144ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 214506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 214606656605SStefano Zampini } 214704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 214804708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 2149511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 215004708bb6SStefano Zampini } 2151ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2152ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 2153ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2154ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 2155ffd830a3SStefano Zampini } 215606656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 215714393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 215814393ed6SStefano Zampini if (need_benign_correction) { 2159df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 216014393ed6SStefano Zampini PetscScalar *marr,*sums; 216114393ed6SStefano Zampini 216214393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 216314393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 2164df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 216514393ed6SStefano Zampini const PetscScalar *vals; 216614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 216714393ed6SStefano Zampini PetscInt n,j,nz; 216814393ed6SStefano Zampini 2169df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2170df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 217114393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 217214393ed6SStefano Zampini PetscInt k; 217314393ed6SStefano Zampini sums[j] = 0.; 217414393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 217514393ed6SStefano Zampini } 217614393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 217714393ed6SStefano Zampini for (j=0;j<n;j++) { 217814393ed6SStefano Zampini PetscScalar val = vals[j]; 217914393ed6SStefano Zampini PetscInt k; 218014393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 218114393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 218214393ed6SStefano Zampini } 218314393ed6SStefano Zampini } 218414393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 2185df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 218614393ed6SStefano Zampini } 218714393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 218814393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 218914393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 219014393ed6SStefano Zampini } 219180677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 219206656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 219306656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 219406656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 219506656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 219606656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 219706656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 219806656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2199d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 2200019a44ceSStefano Zampini } else { 2201d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2202d16cbb6bSStefano Zampini } 220321eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 2204d16cbb6bSStefano Zampini 220506656605SStefano Zampini /* coarse basis functions */ 220606656605SStefano Zampini for (i=0;i<n_vertices;i++) { 220716f15bc4SStefano Zampini PetscScalar *y; 220816f15bc4SStefano Zampini 2209ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 221006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 221106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 221206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 221306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 221406656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 221506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 221606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 221706656605SStefano Zampini 221806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 22194f1b2e48SStefano Zampini PetscInt j; 22204f1b2e48SStefano Zampini 222106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 222206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 222306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 222406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 222506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 22264f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 222706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 222806656605SStefano Zampini } 222906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 223006656605SStefano Zampini } 223104708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 223204708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 223306656605SStefano Zampini } 22345cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 223506656605SStefano Zampini 223606656605SStefano Zampini if (n_constraints) { 223706656605SStefano Zampini Mat B; 223806656605SStefano Zampini 2239ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 224006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 224180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 224206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 224306656605SStefano Zampini if (n_vertices) { 224480677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 224580677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 224680677318SStefano Zampini } else { 224780677318SStefano Zampini Mat S_VCt; 224880677318SStefano Zampini 2249ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2250ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 225172b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 2252ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 2253ffd830a3SStefano Zampini } 225480677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 225580677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 225680677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 225780677318SStefano Zampini } 225806656605SStefano Zampini } 225906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 226006656605SStefano Zampini /* coarse basis functions */ 226106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 226206656605SStefano Zampini PetscScalar *y; 226306656605SStefano Zampini 2264ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 226506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 226606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 226706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 226806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 226906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 227006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 227106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 22724f1b2e48SStefano Zampini PetscInt j; 22734f1b2e48SStefano Zampini 227406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 227506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 227606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 227706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 227806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 22794f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 228006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 228106656605SStefano Zampini } 228206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 228306656605SStefano Zampini } 228406656605SStefano Zampini } 228580677318SStefano Zampini if (n_constraints) { 228680677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 228780677318SStefano Zampini } 22884f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 228972b8c272SStefano Zampini 229072b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 229172b8c272SStefano Zampini if (pcbddc->benign_n) { 229272b8c272SStefano Zampini Mat B0_B,B0_BPHI; 229372b8c272SStefano Zampini IS is_dummy; 229472b8c272SStefano Zampini PetscScalar *data; 229572b8c272SStefano Zampini PetscInt j; 229672b8c272SStefano Zampini 229772b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 229872b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 229972b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 230072b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 230186c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 230272b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 230372b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 230472b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 230572b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 230672b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 230772b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 230872b8c272SStefano Zampini } 230972b8c272SStefano Zampini } 231072b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 231172b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 231272b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 231372b8c272SStefano Zampini } 2314019a44ceSStefano Zampini 231506656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 23163301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 2317ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 2318ffd830a3SStefano Zampini PetscScalar *marray; 231906656605SStefano Zampini 232006656605SStefano Zampini if (n_constraints) { 2321ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 232206656605SStefano Zampini 2323af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 232406656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 2325ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 232616f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 232706656605SStefano Zampini if (n_vertices) { 2328ffd830a3SStefano Zampini Mat S_VCT; 232906656605SStefano Zampini 233006656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 2331ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 233216f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 233306656605SStefano Zampini } 2334ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 233506656605SStefano Zampini } 233616f15bc4SStefano Zampini if (n_vertices && n_R) { 2337ffd830a3SStefano Zampini PetscScalar *av,*marray; 2338ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 2339ffd830a3SStefano Zampini PetscInt n; 2340ffd830a3SStefano Zampini PetscBool flg_row; 234106656605SStefano Zampini 2342ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 2343af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 2344ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2345ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 2346ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2347ffd830a3SStefano Zampini for (i=0;i<n;i++) { 2348ffd830a3SStefano Zampini PetscInt j; 2349ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 2350ffd830a3SStefano Zampini } 2351ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2352ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2353ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 235406656605SStefano Zampini } 235506656605SStefano Zampini 2356ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 2357ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2358ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 2359ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 2360ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 236106656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 236206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 236306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 236406656605SStefano Zampini } 2365ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2366ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 2367ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 2368ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 2369ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 2370ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2371ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2372ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 237306656605SStefano Zampini } 2374ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 237506656605SStefano Zampini /* coarse basis functions */ 237606656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 237706656605SStefano Zampini PetscScalar *y; 237806656605SStefano Zampini 2379ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 238006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 238106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 238206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 238306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 238406656605SStefano Zampini if (i<n_vertices) { 238506656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 238606656605SStefano Zampini } 238706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 238806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 238906656605SStefano Zampini 239006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 239106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 239206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 239306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 239406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 239506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 239606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 239706656605SStefano Zampini } 239806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 239906656605SStefano Zampini } 2400ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2401ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 240206656605SStefano Zampini } 2403d62866d3SStefano Zampini /* free memory */ 240488ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 240506656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 240606656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 240706656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 240806656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2409d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2410d62866d3SStefano Zampini if (n_vertices) { 2411d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2412d62866d3SStefano Zampini } 2413d62866d3SStefano Zampini if (n_constraints) { 2414d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2415d62866d3SStefano Zampini } 241688ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 241788ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 241888ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2419d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 242088ebb749SStefano Zampini Mat coarse_sub_mat; 242125084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 242288ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 242388ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 242488ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 24258bec7fa6SStefano Zampini Mat C_B,CPHI; 24268bec7fa6SStefano Zampini IS is_dummy; 24278bec7fa6SStefano Zampini Vec mones; 242888ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 242988ebb749SStefano Zampini PetscReal real_value; 243088ebb749SStefano Zampini 2431a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2432a3df083aSStefano Zampini Mat A; 2433a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2434a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2435a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2436a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2437a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2438a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2439a3df083aSStefano Zampini } else { 244088ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 244188ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 244288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 244388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2444a3df083aSStefano Zampini } 244588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 244688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2447ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 244888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 244988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 245088ebb749SStefano Zampini } 245188ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 245288ebb749SStefano Zampini 245325084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 24543301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 245525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2456ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 245788ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 245888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 245988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 246088ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 246188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 246288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 246388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 246488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 246588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 246688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 246788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 246888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 246988ebb749SStefano Zampini } else { 247088ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 247188ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 247288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 247388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 247488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 247588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 247688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 247788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 247888ebb749SStefano Zampini } 247988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 248088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 248188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2482511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 24834f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2484fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 2485d12edf2fSStefano Zampini PetscScalar *data,*data2; 24864f1b2e48SStefano Zampini PetscInt j; 2487d12edf2fSStefano Zampini 24884f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2489fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 2490d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 249186c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2492d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2493d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 24944f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 24954f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2496d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 24974f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 24984f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 24994f1b2e48SStefano Zampini } 2500d12edf2fSStefano Zampini } 2501d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2502d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2503d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2504d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2505d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2506d12edf2fSStefano Zampini } 2507d12edf2fSStefano Zampini #if 0 2508d12edf2fSStefano Zampini { 2509d12edf2fSStefano Zampini PetscViewer viewer; 2510d12edf2fSStefano Zampini char filename[256]; 2511ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2512d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2513d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2514ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2515ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2516ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2517d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 251872b8c272SStefano Zampini if (save_change) { 251972b8c272SStefano Zampini Mat phi_B; 252072b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 252172b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 252272b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 252372b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 252472b8c272SStefano Zampini } else { 2525ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2526ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 252772b8c272SStefano Zampini } 2528ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2529ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2530ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2531ffd830a3SStefano Zampini } 2532ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2533ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2534ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2535ffd830a3SStefano Zampini } 253672b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 2537ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2538ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2539ffd830a3SStefano Zampini } 2540d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2541d12edf2fSStefano Zampini } 2542d12edf2fSStefano Zampini #endif 254381d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 25448bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 25451575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 254606656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 25478bec7fa6SStefano Zampini 25488bec7fa6SStefano Zampini /* check constraints */ 2549a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 2550a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 25514f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 25528bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2553a00504b5SStefano Zampini } else { 2554a00504b5SStefano Zampini PetscScalar *data; 2555a00504b5SStefano Zampini Mat tmat; 2556a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2557a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 2558a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 2559a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2560a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2561a00504b5SStefano Zampini } 25628bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 25638bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 25648bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 25658bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2566bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2567ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2568bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2569bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2570bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2571bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2572bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 257388ebb749SStefano Zampini } 25748bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 25758bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 25768bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 25778bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 257825084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 257988ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 258088ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 258188ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 258288ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 258388ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 258488ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 258588ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 258688ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 258788ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 258888ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2589ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 259088ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 259188ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 259288ebb749SStefano Zampini } 259388ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 259488ebb749SStefano Zampini } 25958629588bSStefano Zampini /* get back data */ 25968629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 259788ebb749SStefano Zampini PetscFunctionReturn(0); 259888ebb749SStefano Zampini } 259988ebb749SStefano Zampini 260088ebb749SStefano Zampini #undef __FUNCT__ 2601d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2602d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2603aa0d41d4SStefano Zampini { 2604d65f70fdSStefano Zampini Mat *work_mat; 2605d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2606d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2607c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 2608aa0d41d4SStefano Zampini PetscErrorCode ierr; 2609aa0d41d4SStefano Zampini 2610aa0d41d4SStefano Zampini PetscFunctionBegin; 2611d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2612d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2613d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2614d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2615aa0d41d4SStefano Zampini 2616d65f70fdSStefano Zampini if (!rsorted) { 2617906d46d4SStefano Zampini const PetscInt *idxs; 2618906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2619aa0d41d4SStefano Zampini 2620d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2621d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2622d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2623d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2624aa0d41d4SStefano Zampini } 2625d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2626d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2627d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2628d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2629aa0d41d4SStefano Zampini } 2630d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2631d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2632d65f70fdSStefano Zampini } else { 2633d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2634d65f70fdSStefano Zampini isrow_s = isrow; 2635aa0d41d4SStefano Zampini } 2636906d46d4SStefano Zampini 2637d65f70fdSStefano Zampini if (!csorted) { 2638d65f70fdSStefano Zampini if (isrow == iscol) { 2639d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2640d65f70fdSStefano Zampini iscol_s = isrow_s; 2641d65f70fdSStefano Zampini } else { 2642d65f70fdSStefano Zampini const PetscInt *idxs; 2643d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2644906d46d4SStefano Zampini 2645d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2646d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2647d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2648d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2649d65f70fdSStefano Zampini } 2650d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2651d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2652d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2653d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2654d65f70fdSStefano Zampini } 2655d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2656d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2657d65f70fdSStefano Zampini } 2658d65f70fdSStefano Zampini } else { 2659d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2660d65f70fdSStefano Zampini iscol_s = iscol; 2661d65f70fdSStefano Zampini } 2662d65f70fdSStefano Zampini 2663d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2664d65f70fdSStefano Zampini 2665d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2666906d46d4SStefano Zampini Mat new_mat; 2667d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2668906d46d4SStefano Zampini 2669d65f70fdSStefano Zampini if (!rsorted) { 2670d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2671d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2672d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2673d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2674906d46d4SStefano Zampini } 2675d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2676d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2677d65f70fdSStefano Zampini } else { 2678d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2679906d46d4SStefano Zampini } 2680d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2681d65f70fdSStefano Zampini 2682d65f70fdSStefano Zampini if (!csorted) { 2683d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2684d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2685d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2686d65f70fdSStefano Zampini } else { 2687d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2688d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2689d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2690d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2691d65f70fdSStefano Zampini } 2692d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2693d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2694d65f70fdSStefano Zampini } 2695d65f70fdSStefano Zampini } else { 2696d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2697d65f70fdSStefano Zampini } 2698d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2699d65f70fdSStefano Zampini 2700d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2701d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2702d65f70fdSStefano Zampini work_mat[0] = new_mat; 2703d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2704d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2705d65f70fdSStefano Zampini } 2706d65f70fdSStefano Zampini 2707d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2708d65f70fdSStefano Zampini *B = work_mat[0]; 2709d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2710d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2711d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2712d65f70fdSStefano Zampini PetscFunctionReturn(0); 2713d65f70fdSStefano Zampini } 2714d65f70fdSStefano Zampini 2715d65f70fdSStefano Zampini #undef __FUNCT__ 27165e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 27175e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2718aa0d41d4SStefano Zampini { 2719aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 27205e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2721d65f70fdSStefano Zampini Mat new_mat; 27225e8657edSStefano Zampini IS is_local,is_global; 2723d65f70fdSStefano Zampini PetscInt local_size; 2724d65f70fdSStefano Zampini PetscBool isseqaij; 2725aa0d41d4SStefano Zampini PetscErrorCode ierr; 2726aa0d41d4SStefano Zampini 2727aa0d41d4SStefano Zampini PetscFunctionBegin; 2728aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 27295e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 27305e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2731b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2732aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2733d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2734aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2735906d46d4SStefano Zampini 2736906d46d4SStefano Zampini /* check */ 2737906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2738906d46d4SStefano Zampini Vec x,x_change; 2739906d46d4SStefano Zampini PetscReal error; 2740906d46d4SStefano Zampini 27415e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2742906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 27435e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2744e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2745e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2746d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2747e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2748e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2749906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2750906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2751906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2752906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2753906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2754906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2755906d46d4SStefano Zampini } 2756906d46d4SStefano Zampini 275722d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 27589b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 275922d5777bSStefano Zampini if (isseqaij) { 2760a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2761a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 2762aa0d41d4SStefano Zampini } else { 2763a00504b5SStefano Zampini Mat work_mat; 27641cf9b237SStefano Zampini 2765a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2766aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2767a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 27681d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2769aa0d41d4SStefano Zampini } 27703301b35fSStefano Zampini if (matis->A->symmetric_set) { 27713301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2772e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 27733301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2774e496cd5dSStefano Zampini #endif 27753301b35fSStefano Zampini } 2776d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2777aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2778aa0d41d4SStefano Zampini } 2779aa0d41d4SStefano Zampini 2780aa0d41d4SStefano Zampini #undef __FUNCT__ 2781a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 27828ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2783a64d13efSStefano Zampini { 2784a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2785a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2786d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 278753892102SStefano Zampini PetscInt *idx_R_local=NULL; 27883a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 27893a50541eSStefano Zampini PetscInt vbs,bs; 27906816873aSStefano Zampini PetscBT bitmask=NULL; 2791a64d13efSStefano Zampini PetscErrorCode ierr; 2792a64d13efSStefano Zampini 2793a64d13efSStefano Zampini PetscFunctionBegin; 2794b23d619eSStefano Zampini /* 2795b23d619eSStefano Zampini No need to setup local scatters if 2796b23d619eSStefano Zampini - primal space is unchanged 2797b23d619eSStefano Zampini AND 2798b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2799b23d619eSStefano Zampini AND 2800b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2801b23d619eSStefano Zampini */ 2802b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2803f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2804f4ddd8eeSStefano Zampini } 2805f4ddd8eeSStefano Zampini /* destroy old objects */ 2806f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2807f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2808f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2809a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2810b371cd4fSStefano Zampini n_B = pcis->n_B; 2811b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2812b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 28133a50541eSStefano Zampini 2814a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 28156816873aSStefano Zampini 281653892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 2817df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2818854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2819a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2820a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 28210e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2822a64d13efSStefano Zampini } 2823a64d13efSStefano Zampini 2824a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 28254641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 28266816873aSStefano Zampini idx_R_local[n_R++] = i; 2827a64d13efSStefano Zampini } 2828a64d13efSStefano Zampini } 2829df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 2830df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 28316816873aSStefano Zampini 2832df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2833df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 28346816873aSStefano Zampini } 28353a50541eSStefano Zampini 28363a50541eSStefano Zampini /* Block code */ 28373a50541eSStefano Zampini vbs = 1; 28383a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 28393a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 28403a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 28413a50541eSStefano Zampini PetscInt *vary; 2842df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2843785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 28443a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2845d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2846d3df7717SStefano 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 */ 28470e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2848d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 28493a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 28503a50541eSStefano Zampini is_blocked = PETSC_FALSE; 28513a50541eSStefano Zampini break; 28523a50541eSStefano Zampini } 28533a50541eSStefano Zampini } 2854d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2855d3df7717SStefano Zampini } else { 2856d3df7717SStefano Zampini /* Verify directly the R set */ 2857d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2858d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2859d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2860d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2861d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2862d3df7717SStefano Zampini break; 2863d3df7717SStefano Zampini } 2864d3df7717SStefano Zampini } 2865d3df7717SStefano Zampini } 2866d3df7717SStefano Zampini } 28673a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 28683a50541eSStefano Zampini vbs = bs; 28693a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 28703a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 28713a50541eSStefano Zampini } 28723a50541eSStefano Zampini } 28733a50541eSStefano Zampini } 28743a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 2875df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2876df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 287753892102SStefano Zampini 2878df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2879df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 288053892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 2881df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 288253892102SStefano Zampini } else { 28833a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 288453892102SStefano Zampini } 2885a64d13efSStefano Zampini 2886a64d13efSStefano Zampini /* print some info if requested */ 2887a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2888a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2889a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 28901575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2891a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2892a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 28934f1b2e48SStefano 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); 2894a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2895a64d13efSStefano Zampini } 2896a64d13efSStefano Zampini 2897a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 2898df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 28996816873aSStefano Zampini IS is_aux1,is_aux2; 29006816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 29016816873aSStefano Zampini 29023a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2903854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2904854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2905a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 29064641a718SStefano Zampini for (i=0; i<n_D; i++) { 29074641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 29084641a718SStefano Zampini } 2909a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2910a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 29114641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 29124641a718SStefano Zampini aux_array1[j++] = i; 2913a64d13efSStefano Zampini } 2914a64d13efSStefano Zampini } 2915a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2916a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2917a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 29184641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 29194641a718SStefano Zampini aux_array2[j++] = i; 2920a64d13efSStefano Zampini } 2921a64d13efSStefano Zampini } 2922a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2923a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2924a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2925a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2926a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2927a64d13efSStefano Zampini 29288eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2929785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2930a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 29314641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 29324641a718SStefano Zampini aux_array1[j++] = i; 2933a64d13efSStefano Zampini } 2934a64d13efSStefano Zampini } 2935a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2936a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2937a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2938a64d13efSStefano Zampini } 29394641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 29403a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2941d62866d3SStefano Zampini } else { 2942df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 29436816873aSStefano Zampini IS tis; 29446816873aSStefano Zampini PetscInt schur_size; 29456816873aSStefano Zampini 2946df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 29476816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 2948df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 29496816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 29506816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 29516816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 29526816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 29536816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2954d62866d3SStefano Zampini } 2955d62866d3SStefano Zampini } 2956a64d13efSStefano Zampini PetscFunctionReturn(0); 2957a64d13efSStefano Zampini } 2958a64d13efSStefano Zampini 2959304d26faSStefano Zampini 2960304d26faSStefano Zampini #undef __FUNCT__ 2961304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2962684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2963304d26faSStefano Zampini { 2964304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2965304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2966304d26faSStefano Zampini PC pc_temp; 2967304d26faSStefano Zampini Mat A_RR; 2968f4ddd8eeSStefano Zampini MatReuse reuse; 2969304d26faSStefano Zampini PetscScalar m_one = -1.0; 2970304d26faSStefano Zampini PetscReal value; 297104708bb6SStefano Zampini PetscInt n_D,n_R; 2972c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 2973304d26faSStefano Zampini PetscErrorCode ierr; 2974e604994aSStefano Zampini /* prefixes stuff */ 2975312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2976e604994aSStefano Zampini size_t len; 2977304d26faSStefano Zampini 2978304d26faSStefano Zampini PetscFunctionBegin; 2979304d26faSStefano Zampini 2980e604994aSStefano Zampini /* compute prefixes */ 2981e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2982e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2983e604994aSStefano Zampini if (!pcbddc->current_level) { 2984e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2985e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2986e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2987e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2988e604994aSStefano Zampini } else { 2989e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2990312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2991e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2992e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2993312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2994312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 299534d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 299634d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2997e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2998e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2999e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 3000e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 3001e604994aSStefano Zampini } 3002e604994aSStefano Zampini 3003304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 3004684f6988SStefano Zampini if (dirichlet) { 3005d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3006450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3007450f8f5eSStefano Zampini if (!sub_schurs->reuse_solver) { 3008450f8f5eSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 3009450f8f5eSStefano Zampini } 3010450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 3011a3df083aSStefano Zampini Mat A_IIn; 3012a3df083aSStefano Zampini 3013a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 3014a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 3015a3df083aSStefano Zampini pcis->A_II = A_IIn; 3016a3df083aSStefano Zampini } 3017450f8f5eSStefano Zampini } 30183301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 30193301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 3020964fefecSStefano Zampini } 3021ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 3022964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 3023304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 3024304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 3025304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 3026304d26faSStefano Zampini /* default */ 3027304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 3028e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 30299577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 3030304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 30319577ea80SStefano Zampini if (issbaij) { 30329577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 30339577ea80SStefano Zampini } else { 3034304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 30359577ea80SStefano Zampini } 3036304d26faSStefano Zampini /* Allow user's customization */ 3037304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 3038304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3039304d26faSStefano Zampini } 3040d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 3041df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 3042df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3043d62866d3SStefano Zampini 3044df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 3045d5574798SStefano Zampini } 3046304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3047304d26faSStefano Zampini if (!n_D) { 3048304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 3049304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3050304d26faSStefano Zampini } 3051304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 3052304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 3053304d26faSStefano Zampini /* set ksp_D into pcis data */ 3054304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 3055304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 3056304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 3057684f6988SStefano Zampini } 3058304d26faSStefano Zampini 3059304d26faSStefano Zampini /* NEUMANN PROBLEM */ 3060684f6988SStefano Zampini A_RR = 0; 3061684f6988SStefano Zampini if (neumann) { 3062d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 306304708bb6SStefano Zampini PetscInt ibs,mbs; 306404708bb6SStefano Zampini PetscBool issbaij; 306504708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3066f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 30678ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 3068f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 3069f4ddd8eeSStefano Zampini PetscInt nn_R; 307081d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 3071f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3072f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 3073f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 3074f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 3075f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3076f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3077f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 3078727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 3079f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3080f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3081f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 3082f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 3083f4ddd8eeSStefano Zampini } 3084f4ddd8eeSStefano Zampini } 3085f4ddd8eeSStefano Zampini /* last check */ 3086d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 3087f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3088f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3089f4ddd8eeSStefano Zampini } 3090f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 3091f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 3092f4ddd8eeSStefano Zampini } 3093a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 3094af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 3095af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 309604708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 309704708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 309804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 309904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 310004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 3101af732b37SStefano Zampini } else { 3102511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 31036816873aSStefano Zampini } 310404708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 310504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 310604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 310704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 310804708bb6SStefano Zampini } else { 3109511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 311004708bb6SStefano Zampini } 311104708bb6SStefano Zampini } 3112a00504b5SStefano Zampini /* extract A_RR */ 3113a00504b5SStefano Zampini if (sub_schurs->reuse_solver) { 3114a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3115a00504b5SStefano Zampini 3116a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 311716e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3118a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 311916e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 312016e386b8SStefano Zampini } else { 3121a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 3122a00504b5SStefano Zampini } 3123a00504b5SStefano Zampini } else { 3124a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3125a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 3126a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 3127a00504b5SStefano Zampini } 3128a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 3129f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 313016e386b8SStefano Zampini } 31313301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 31323301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 31336816873aSStefano Zampini } 3134f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 3135304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 3136304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 3137304d26faSStefano Zampini /* default */ 3138304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 3139e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 3140304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 31419577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 31429577ea80SStefano Zampini if (issbaij) { 31439577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 31449577ea80SStefano Zampini } else { 3145304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 31469577ea80SStefano Zampini } 3147304d26faSStefano Zampini /* Allow user's customization */ 3148304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 3149304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3150304d26faSStefano Zampini } 3151304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3152304d26faSStefano Zampini if (!n_R) { 3153304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 3154304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3155304d26faSStefano Zampini } 31565cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 3157df4d28bfSStefano Zampini /* Reuse solver if it is present */ 3158df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 3159df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3160d62866d3SStefano Zampini 3161df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 3162d62866d3SStefano Zampini } 3163304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 3164304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 3165684f6988SStefano Zampini } 3166304d26faSStefano Zampini 3167684f6988SStefano Zampini if (pcbddc->dbg_flag) { 3168684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 31691575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3170684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3171684f6988SStefano Zampini } 3172c7017625SStefano Zampini 3173c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 3174c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 3175c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 3176c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 3177c7017625SStefano Zampini } 3178c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 3179c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 3180c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 3181c7017625SStefano Zampini } 3182c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 3183c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 3184c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 3185c7017625SStefano Zampini } 3186c7017625SStefano Zampini 3187c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 3188c7017625SStefano Zampini if (pcbddc->dbg_flag) { 3189684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 31900fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 31910fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 31920fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 31930fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 31940fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 3195e604994aSStefano 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); 3196c7017625SStefano Zampini if (check_corr[0]) { 3197c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 3198c7017625SStefano Zampini } 3199304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3200304d26faSStefano Zampini } 3201684f6988SStefano Zampini if (neumann) { /* Neumann */ 32020fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 32030fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 32040fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 32050fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 32060fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 3207e604994aSStefano 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); 3208c7017625SStefano Zampini if (check_corr[1]) { 3209c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 3210c7017625SStefano Zampini } 3211304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3212304d26faSStefano Zampini } 3213684f6988SStefano Zampini } 32145cbda25cSStefano Zampini /* free Neumann problem's matrix */ 32155cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 3216304d26faSStefano Zampini PetscFunctionReturn(0); 3217304d26faSStefano Zampini } 3218304d26faSStefano Zampini 3219304d26faSStefano Zampini #undef __FUNCT__ 3220ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 322180677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 3222674ae819SStefano Zampini { 3223674ae819SStefano Zampini PetscErrorCode ierr; 3224674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3225be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3226674ae819SStefano Zampini 3227674ae819SStefano Zampini PetscFunctionBegin; 3228df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 322980677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 323020c7b377SStefano Zampini } 323180677318SStefano Zampini if (!pcbddc->switch_static) { 323280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 323380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 323480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 323520c7b377SStefano Zampini } 3236df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 323780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 323880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 323920c7b377SStefano Zampini } else { 3240df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3241be83ff47SStefano Zampini 3242df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3243df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 324420c7b377SStefano Zampini } 3245be83ff47SStefano Zampini } else { 324680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 324780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 324880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 324980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 325080677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 325180677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 325280677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 325380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 325480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3255674ae819SStefano Zampini } 3256674ae819SStefano Zampini } 325772b8c272SStefano Zampini if (!sub_schurs->reuse_solver || pcbddc->switch_static) { 325880677318SStefano Zampini if (applytranspose) { 325980677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 326080677318SStefano Zampini } else { 326180677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 326280677318SStefano Zampini } 3263be83ff47SStefano Zampini } else { 3264df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3265be83ff47SStefano Zampini 3266be83ff47SStefano Zampini if (applytranspose) { 3267df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3268be83ff47SStefano Zampini } else { 3269df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 3270be83ff47SStefano Zampini } 3271be83ff47SStefano Zampini } 327280677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 327380677318SStefano Zampini if (!pcbddc->switch_static) { 3274df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 327580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 327680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3277be83ff47SStefano Zampini } else { 3278df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3279be83ff47SStefano Zampini 3280df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3281df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3282be83ff47SStefano Zampini } 328380677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 328480677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 328580677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 328680677318SStefano Zampini } 328780677318SStefano Zampini } else { 328880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 328980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 329380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 329480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 329580677318SStefano Zampini } 329680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3300674ae819SStefano Zampini } 3301674ae819SStefano Zampini PetscFunctionReturn(0); 3302674ae819SStefano Zampini } 3303674ae819SStefano Zampini 3304dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 3305674ae819SStefano Zampini #undef __FUNCT__ 3306674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 3307dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 3308674ae819SStefano Zampini { 3309674ae819SStefano Zampini PetscErrorCode ierr; 3310674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3311674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 3312674ae819SStefano Zampini const PetscScalar zero = 0.0; 3313674ae819SStefano Zampini 3314674ae819SStefano Zampini PetscFunctionBegin; 3315dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 33164fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3317dc359a40SStefano Zampini if (applytranspose) { 3318674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 33198eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 3320dc359a40SStefano Zampini } else { 3321674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 3322674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 332315aaf578SStefano Zampini } 33244fee134fSStefano Zampini } else { 33254fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 33264fee134fSStefano Zampini } 3327efc2fbd9SStefano Zampini 3328efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 33294f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3330efc2fbd9SStefano Zampini PetscScalar *array; 33314f1b2e48SStefano Zampini PetscInt j; 3332efc2fbd9SStefano Zampini 3333efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 33344f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 3335efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3336efc2fbd9SStefano Zampini } 3337efc2fbd9SStefano Zampini 333812edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 333912edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 334012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 334112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 334212edc857SStefano Zampini 33439f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 334412edc857SStefano Zampini if (pcbddc->coarse_ksp) { 334551694757SStefano Zampini Mat coarse_mat; 3346964fefecSStefano Zampini Vec rhs,sol; 334751694757SStefano Zampini MatNullSpace nullsp; 334827b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 3349964fefecSStefano Zampini 335027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 335127b6a85dSStefano Zampini PC coarse_pc; 335227b6a85dSStefano Zampini 335327b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 335427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 335527b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 335627b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 335727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 335827b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 33593bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 336027b6a85dSStefano Zampini } 336127b6a85dSStefano Zampini } 3362964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 3363964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 336451694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 336551694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 336651694757SStefano Zampini if (nullsp) { 336751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 336851694757SStefano Zampini } 336912edc857SStefano Zampini if (applytranspose) { 33701f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only) { 33711f4df5f7SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 33722701bc32SStefano Zampini } else { 3373964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 33742701bc32SStefano Zampini } 33752701bc32SStefano Zampini } else { 33761f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 33772701bc32SStefano Zampini PC coarse_pc; 33782701bc32SStefano Zampini 33792701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 33802701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 33813e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 33822701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 338312edc857SStefano Zampini } else { 3384964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 338512edc857SStefano Zampini } 33862701bc32SStefano Zampini } 33871d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 338827b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 338927b6a85dSStefano Zampini PC coarse_pc; 339027b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 339127b6a85dSStefano Zampini 339227b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 339327b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 339427b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 33953bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 339627b6a85dSStefano Zampini } 339751694757SStefano Zampini if (nullsp) { 339851694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 339951694757SStefano Zampini } 340012edc857SStefano Zampini } 3401674ae819SStefano Zampini 3402674ae819SStefano Zampini /* Local solution on R nodes */ 34034fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 340480677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 34059f00e9b4SStefano Zampini } 34069f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 34079f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 340812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3409674ae819SStefano Zampini 34104fee134fSStefano Zampini /* Sum contributions from the two levels */ 34114fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 3412dc359a40SStefano Zampini if (applytranspose) { 3413dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3414dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3415dc359a40SStefano Zampini } else { 3416674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 34178eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3418dc359a40SStefano Zampini } 3419efc2fbd9SStefano Zampini /* store p0 */ 34204f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3421efc2fbd9SStefano Zampini PetscScalar *array; 34224f1b2e48SStefano Zampini PetscInt j; 3423efc2fbd9SStefano Zampini 3424efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 34254f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 3426efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3427efc2fbd9SStefano Zampini } 34284fee134fSStefano Zampini } else { /* expand the coarse solution */ 34294fee134fSStefano Zampini if (applytranspose) { 34304fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 34314fee134fSStefano Zampini } else { 34324fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 34334fee134fSStefano Zampini } 34344fee134fSStefano Zampini } 3435674ae819SStefano Zampini PetscFunctionReturn(0); 3436674ae819SStefano Zampini } 3437674ae819SStefano Zampini 3438674ae819SStefano Zampini #undef __FUNCT__ 3439674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 344012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 3441674ae819SStefano Zampini { 3442674ae819SStefano Zampini PetscErrorCode ierr; 3443674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 344458da7f69SStefano Zampini PetscScalar *array; 344512edc857SStefano Zampini Vec from,to; 3446674ae819SStefano Zampini 3447674ae819SStefano Zampini PetscFunctionBegin; 344812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 344912edc857SStefano Zampini from = pcbddc->coarse_vec; 345012edc857SStefano Zampini to = pcbddc->vec1_P; 345112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 345212edc857SStefano Zampini Vec tvec; 345358da7f69SStefano Zampini 345458da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 345558da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 345612edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 345758da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 345858da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 345958da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 346012edc857SStefano Zampini } 346112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 346212edc857SStefano Zampini from = pcbddc->vec1_P; 346312edc857SStefano Zampini to = pcbddc->coarse_vec; 346412edc857SStefano Zampini } 346512edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3466674ae819SStefano Zampini PetscFunctionReturn(0); 3467674ae819SStefano Zampini } 3468674ae819SStefano Zampini 3469674ae819SStefano Zampini #undef __FUNCT__ 3470674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 347112edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3472674ae819SStefano Zampini { 3473674ae819SStefano Zampini PetscErrorCode ierr; 3474674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 347558da7f69SStefano Zampini PetscScalar *array; 347612edc857SStefano Zampini Vec from,to; 3477674ae819SStefano Zampini 3478674ae819SStefano Zampini PetscFunctionBegin; 347912edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 348012edc857SStefano Zampini from = pcbddc->coarse_vec; 348112edc857SStefano Zampini to = pcbddc->vec1_P; 348212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 348312edc857SStefano Zampini from = pcbddc->vec1_P; 348412edc857SStefano Zampini to = pcbddc->coarse_vec; 348512edc857SStefano Zampini } 348612edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 348712edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 348812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 348912edc857SStefano Zampini Vec tvec; 349058da7f69SStefano Zampini 349112edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 349258da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 349358da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 349458da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 349558da7f69SStefano Zampini } 349658da7f69SStefano Zampini } else { 349758da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 349858da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 349912edc857SStefano Zampini } 350012edc857SStefano Zampini } 3501674ae819SStefano Zampini PetscFunctionReturn(0); 3502674ae819SStefano Zampini } 3503674ae819SStefano Zampini 3504984c4197SStefano Zampini /* uncomment for testing purposes */ 3505984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3506674ae819SStefano Zampini #undef __FUNCT__ 3507674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3508674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3509674ae819SStefano Zampini { 3510674ae819SStefano Zampini PetscErrorCode ierr; 3511674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3512674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3513674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3514984c4197SStefano Zampini /* one and zero */ 3515984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3516984c4197SStefano Zampini /* space to store constraints and their local indices */ 35179162d606SStefano Zampini PetscScalar *constraints_data; 35189162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 35199162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 35209162d606SStefano Zampini PetscInt *constraints_n; 3521984c4197SStefano Zampini /* iterators */ 3522b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3523984c4197SStefano Zampini /* BLAS integers */ 3524e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3525e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3526c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3527727cdba6SStefano Zampini /* reuse */ 35280e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 35290e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3530984c4197SStefano Zampini /* change of basis */ 3531b3d85658SStefano Zampini PetscBool qr_needed; 35329162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3533984c4197SStefano Zampini /* auxiliary stuff */ 353464efe560SStefano Zampini PetscInt *nnz,*is_indices; 35358a0068c3SStefano Zampini PetscInt ncc; 3536984c4197SStefano Zampini /* some quantities */ 353745a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3538a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3539984c4197SStefano Zampini 3540674ae819SStefano Zampini PetscFunctionBegin; 35418e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 35428e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 35438e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 354416909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 3545088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3546088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 35470e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 35480e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 35490e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 35500e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 35510e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3552088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3553cf5a6209SStefano Zampini 3554cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 35559162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3556cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3557cf5a6209SStefano Zampini const Vec *nearnullvecs; 3558cf5a6209SStefano Zampini Vec *localnearnullsp; 3559cf5a6209SStefano Zampini PetscScalar *array; 3560cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3561cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3562674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3563b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3564674ae819SStefano Zampini PetscScalar *work; 3565674ae819SStefano Zampini PetscReal *singular_vals; 3566674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3567674ae819SStefano Zampini PetscReal *rwork; 3568674ae819SStefano Zampini #endif 3569674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3570674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3571674ae819SStefano Zampini #else 3572964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3573964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3574674ae819SStefano Zampini #endif 3575674ae819SStefano Zampini 3576674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3577d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3578e4d548c7SStefano Zampini /* print some info */ 35791f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 3580e4d548c7SStefano Zampini PetscInt nv; 3581e4d548c7SStefano Zampini 3582e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 3583e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 3584e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3585e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3586e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3587e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 3588e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 3589e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3590e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3591e4d548c7SStefano Zampini } 3592e4d548c7SStefano Zampini 3593d06fc5fdSStefano Zampini /* free unneeded index sets */ 3594d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3595d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3596674ae819SStefano Zampini } 3597d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3598d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3599d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3600d06fc5fdSStefano Zampini } 3601d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3602d06fc5fdSStefano Zampini n_ISForEdges = 0; 3603d06fc5fdSStefano Zampini } 3604d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3605d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3606d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3607d06fc5fdSStefano Zampini } 3608d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3609d06fc5fdSStefano Zampini n_ISForFaces = 0; 3610d06fc5fdSStefano Zampini } 361170022509SStefano Zampini 3612674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3613674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3614674ae819SStefano Zampini if (nearnullsp) { 3615674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3616f4ddd8eeSStefano Zampini /* remove any stored info */ 3617f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3618f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3619f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3620f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3621f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3622473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3623f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3624f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3625f4ddd8eeSStefano Zampini } 3626984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3627984c4197SStefano Zampini nnsp_size = 0; 3628674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3629674ae819SStefano Zampini } 3630984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3631984c4197SStefano Zampini max_constraints = nnsp_size; 3632984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3633984c4197SStefano Zampini 3634674ae819SStefano Zampini /* 3635674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 36369162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 36379162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 36389162d606SStefano Zampini There can be multiple constraints per connected component 3639674ae819SStefano Zampini */ 3640674ae819SStefano Zampini n_vertices = 0; 3641674ae819SStefano Zampini if (ISForVertices) { 3642674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3643674ae819SStefano Zampini } 36449162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 36459162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 36469162d606SStefano Zampini 36479162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 36489162d606SStefano Zampini total_counts *= max_constraints; 3649674ae819SStefano Zampini total_counts += n_vertices; 36504641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 36519162d606SStefano Zampini 3652674ae819SStefano Zampini total_counts = 0; 3653674ae819SStefano Zampini max_size_of_constraint = 0; 3654674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 36559162d606SStefano Zampini IS used_is; 3656674ae819SStefano Zampini if (i<n_ISForEdges) { 36579162d606SStefano Zampini used_is = ISForEdges[i]; 3658674ae819SStefano Zampini } else { 36599162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3660674ae819SStefano Zampini } 36619162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3662674ae819SStefano Zampini total_counts += j; 3663674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3664674ae819SStefano Zampini } 36659162d606SStefano 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); 36669162d606SStefano Zampini 3667984c4197SStefano Zampini /* get local part of global near null space vectors */ 3668785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3669984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3670984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3671e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3672e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3673984c4197SStefano Zampini } 3674674ae819SStefano Zampini 3675242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3676242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3677a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3678242a89d7SStefano Zampini 3679984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3680a773dcb8SStefano Zampini if (!skip_lapack) { 3681674ae819SStefano Zampini PetscScalar temp_work; 3682911cabfeSStefano Zampini 3683674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3684984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3685785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3686785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3687785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3688674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3689785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3690674ae819SStefano Zampini #endif 3691674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3692c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3693c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3694674ae819SStefano Zampini lwork = -1; 3695674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3696674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3697c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3698674ae819SStefano Zampini #else 3699c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3700674ae819SStefano Zampini #endif 3701674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3702984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3703674ae819SStefano Zampini #else /* on missing GESVD */ 3704674ae819SStefano Zampini /* SVD */ 3705674ae819SStefano Zampini PetscInt max_n,min_n; 3706674ae819SStefano Zampini max_n = max_size_of_constraint; 3707984c4197SStefano Zampini min_n = max_constraints; 3708984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3709674ae819SStefano Zampini min_n = max_size_of_constraint; 3710984c4197SStefano Zampini max_n = max_constraints; 3711674ae819SStefano Zampini } 3712785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3713674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3714785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3715674ae819SStefano Zampini #endif 3716674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3717674ae819SStefano Zampini lwork = -1; 3718e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3719e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3720b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3721674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3722674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 37239162d606SStefano 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)); 3724674ae819SStefano Zampini #else 37259162d606SStefano 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)); 3726674ae819SStefano Zampini #endif 3727674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3728984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3729984c4197SStefano Zampini #endif /* on missing GESVD */ 3730674ae819SStefano Zampini /* Allocate optimal workspace */ 3731674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3732854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3733674ae819SStefano Zampini } 3734674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3735674ae819SStefano Zampini total_counts = 0; 37369162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 37379162d606SStefano Zampini constraints_data_ptr[0] = 0; 3738674ae819SStefano Zampini /* vertices */ 37399162d606SStefano Zampini if (n_vertices) { 3740674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 37419162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3742674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 37439162d606SStefano Zampini constraints_n[total_counts] = 1; 37449162d606SStefano Zampini constraints_data[total_counts] = 1.0; 37459162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 37469162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3747674ae819SStefano Zampini total_counts++; 3748674ae819SStefano Zampini } 3749674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3750674ae819SStefano Zampini n_vertices = total_counts; 3751674ae819SStefano Zampini } 3752984c4197SStefano Zampini 3753674ae819SStefano Zampini /* edges and faces */ 37549162d606SStefano Zampini total_counts_cc = total_counts; 3755911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 37569162d606SStefano Zampini IS used_is; 37579162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 37589162d606SStefano Zampini 3759911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 37609162d606SStefano Zampini used_is = ISForEdges[ncc]; 3761984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3762674ae819SStefano Zampini } else { 37639162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3764984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3765674ae819SStefano Zampini } 3766674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 37679162d606SStefano Zampini 37689162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 37699162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3770984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3771984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3772674ae819SStefano Zampini if (nnsp_has_cnst) { 37735b08dc53SStefano Zampini PetscScalar quad_value; 37749162d606SStefano Zampini 37759162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 37769162d606SStefano Zampini idxs_copied = PETSC_TRUE; 37779162d606SStefano Zampini 3778a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3779674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3780a773dcb8SStefano Zampini } else { 3781a773dcb8SStefano Zampini quad_value = 1.0; 3782a773dcb8SStefano Zampini } 3783674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 37849162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3785674ae819SStefano Zampini } 37869162d606SStefano Zampini temp_constraints++; 3787674ae819SStefano Zampini total_counts++; 3788674ae819SStefano Zampini } 3789674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3790984c4197SStefano Zampini PetscReal real_value; 37919162d606SStefano Zampini PetscScalar *ptr_to_data; 37929162d606SStefano Zampini 3793984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 37949162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3795674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 37969162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3797674ae819SStefano Zampini } 3798984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3799984c4197SStefano Zampini /* check if array is null on the connected component */ 3800e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 38019162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 38025b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3803674ae819SStefano Zampini temp_constraints++; 3804674ae819SStefano Zampini total_counts++; 38059162d606SStefano Zampini if (!idxs_copied) { 38069162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 38079162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3808674ae819SStefano Zampini } 3809674ae819SStefano Zampini } 38109162d606SStefano Zampini } 38119162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 381245a1bb75SStefano Zampini valid_constraints = temp_constraints; 3813eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3814a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 38159162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 38169162d606SStefano Zampini 38179162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3818a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 38199162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3820a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 38219162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3822a773dcb8SStefano Zampini } else { /* perform SVD */ 3823984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 38249162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3825674ae819SStefano Zampini 3826674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3827984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3828984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3829984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3830984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3831984c4197SStefano Zampini from that computed using LAPACKgesvd 3832984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3833984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3834984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3835674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3836e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3837984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3838674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3839674ae819SStefano Zampini for (k=0;k<j+1;k++) { 38409162d606SStefano 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)); 3841674ae819SStefano Zampini } 3842674ae819SStefano Zampini } 3843e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3844e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3845e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3846674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3847c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3848674ae819SStefano Zampini #else 3849c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3850674ae819SStefano Zampini #endif 3851674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3852984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3853984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3854674ae819SStefano Zampini j = 0; 3855984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3856674ae819SStefano Zampini total_counts = total_counts-j; 385745a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3858e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3859c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3860c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3861c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3862c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3863c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3864c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3865674ae819SStefano Zampini if (j<temp_constraints) { 3866984c4197SStefano Zampini PetscInt ii; 3867984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3868674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38699162d606SStefano 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)); 3870674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3871984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3872674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 38739162d606SStefano 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]; 3874674ae819SStefano Zampini } 3875674ae819SStefano Zampini } 3876674ae819SStefano Zampini } 3877674ae819SStefano Zampini #else /* on missing GESVD */ 3878e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3879e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3880b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3881674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3882674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 38839162d606SStefano 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)); 3884674ae819SStefano Zampini #else 38859162d606SStefano 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)); 3886674ae819SStefano Zampini #endif 3887984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3888674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3889984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3890e310c8b4SStefano Zampini k = temp_constraints; 3891e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3892674ae819SStefano Zampini j = 0; 3893e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 389445a1bb75SStefano Zampini valid_constraints = k-j; 3895911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3896984c4197SStefano Zampini #endif /* on missing GESVD */ 3897674ae819SStefano Zampini } 3898a773dcb8SStefano Zampini } 38999162d606SStefano Zampini /* update pointers information */ 39009162d606SStefano Zampini if (valid_constraints) { 39019162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 39029162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 39039162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 39049162d606SStefano Zampini /* set change_of_basis flag */ 390545a1bb75SStefano Zampini if (boolforchange) { 3906b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 39079162d606SStefano Zampini } 3908b3d85658SStefano Zampini total_counts_cc++; 390945a1bb75SStefano Zampini } 391045a1bb75SStefano Zampini } 3911984c4197SStefano Zampini /* free workspace */ 39128f1c130eSStefano Zampini if (!skip_lapack) { 3913984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3914984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3915984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3916984c4197SStefano Zampini #endif 3917984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3918984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3919984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3920984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3921984c4197SStefano Zampini #endif 3922984c4197SStefano Zampini } 3923984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3924984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3925984c4197SStefano Zampini } 3926984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3927cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3928cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3929cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3930cf5a6209SStefano Zampini } 3931cf5a6209SStefano Zampini if (n_ISForFaces) { 3932cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3933cf5a6209SStefano Zampini } 3934cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3935cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3936cf5a6209SStefano Zampini } 3937cf5a6209SStefano Zampini if (n_ISForEdges) { 3938cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3939cf5a6209SStefano Zampini } 3940cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 394108122e43SStefano Zampini } else { 394208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3943984c4197SStefano Zampini 394408122e43SStefano Zampini total_counts = 0; 394508122e43SStefano Zampini n_vertices = 0; 3946d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3947d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 394808122e43SStefano Zampini } 394908122e43SStefano Zampini max_constraints = 0; 39509162d606SStefano Zampini total_counts_cc = 0; 395108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 395208122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 39539162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 395408122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 395508122e43SStefano Zampini } 39569162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 39579162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 39589162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 39599162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 396074d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 39619162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 39629162d606SStefano Zampini total_counts_cc = 0; 39639162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 39649162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 39659162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 396608122e43SStefano Zampini } 396708122e43SStefano Zampini } 39689162d606SStefano Zampini #if 0 39699162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 39709162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 39719162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 39729162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 39739162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 39749162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 39759162d606SStefano Zampini } 39769162d606SStefano Zampini printf("\n"); 39779162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 39789162d606SStefano Zampini } 39791b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 39808bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 39811b968477SStefano Zampini } 39821b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 39838bec7fa6SStefano 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]); 39841b968477SStefano Zampini } 398508122e43SStefano Zampini #endif 398608122e43SStefano Zampini 39878bec7fa6SStefano Zampini max_size_of_constraint = 0; 39889162d606SStefano 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]); 39899162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 399008122e43SStefano Zampini /* Change of basis */ 3991b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 399208122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 399308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 399408122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3995b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 399608122e43SStefano Zampini } 399708122e43SStefano Zampini } 399808122e43SStefano Zampini } 399908122e43SStefano Zampini } 4000984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 40014f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 400208122e43SStefano Zampini 40039162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 40049162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 40056c4ed002SBarry 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); 4006674ae819SStefano Zampini 4007674ae819SStefano Zampini /* Create constraint matrix */ 4008674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 400916f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 4010984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 4011984c4197SStefano Zampini 4012984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 4013a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 4014a717540cSStefano Zampini qr_needed = PETSC_FALSE; 401574d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 4016984c4197SStefano Zampini total_primal_vertices=0; 4017b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 40189162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 40199162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 402072b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 40219162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 4022b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 402364efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 40249162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 40259162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 4026a717540cSStefano Zampini } 4027b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 402891af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 4029a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 4030a717540cSStefano Zampini qr_needed = PETSC_TRUE; 4031a717540cSStefano Zampini } 4032fa434743SStefano Zampini } else { 4033b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 4034fa434743SStefano Zampini } 4035a717540cSStefano Zampini } 4036b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 4037b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 4038674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 403970022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4040b3d85658SStefano Zampini 40414f1b2e48SStefano 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); 40420e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 40430e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 4044984c4197SStefano Zampini 4045984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 404674d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 4047785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 4048984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 404974d5cdf7SStefano Zampini 4050984c4197SStefano Zampini j = total_primal_vertices; 405174d5cdf7SStefano Zampini total_counts = total_primal_vertices; 4052b3d85658SStefano Zampini cum = total_primal_vertices; 40539162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 40544641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 4055b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 4056b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 4057b3d85658SStefano Zampini cum++; 40589162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 405974d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 406074d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 406174d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 406274d5cdf7SStefano Zampini } 40639162d606SStefano Zampini j += constraints_n[i]; 4064674ae819SStefano Zampini } 4065674ae819SStefano Zampini } 4066674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 4067674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 4068088faed8SStefano Zampini 4069674ae819SStefano Zampini /* set values in constraint matrix */ 4070984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 40710e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4072674ae819SStefano Zampini } 4073984c4197SStefano Zampini total_counts = total_primal_vertices; 40749162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 40754641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 40769162d606SStefano Zampini PetscInt *cols; 40779162d606SStefano Zampini 40789162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 40799162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 40809162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 40819162d606SStefano Zampini PetscInt row = total_counts+k; 40829162d606SStefano Zampini PetscScalar *vals; 40839162d606SStefano Zampini 40849162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 40859162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 40869162d606SStefano Zampini } 40879162d606SStefano Zampini total_counts += constraints_n[i]; 4088674ae819SStefano Zampini } 4089674ae819SStefano Zampini } 4090674ae819SStefano Zampini /* assembling */ 4091674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4092674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4093088faed8SStefano Zampini 4094984c4197SStefano Zampini /* 40956a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4096984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 4097f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 4098984c4197SStefano Zampini */ 4099674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 4100674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 4101026de310SStefano Zampini /* dual and primal dofs on a single cc */ 4102984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 4103984c4197SStefano Zampini /* working stuff for GEQRF */ 410481d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 4105984c4197SStefano Zampini PetscBLASInt lqr_work; 4106984c4197SStefano Zampini /* working stuff for UNGQR */ 4107984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 4108984c4197SStefano Zampini PetscBLASInt lgqr_work; 4109984c4197SStefano Zampini /* working stuff for TRTRS */ 4110984c4197SStefano Zampini PetscScalar *trs_rhs; 41113f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 4112984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 4113984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 4114984c4197SStefano Zampini PetscScalar *start_vals; 4115984c4197SStefano Zampini /* working stuff for values insertion */ 41164641a718SStefano Zampini PetscBT is_primal; 411764efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 4118906d46d4SStefano Zampini /* matrix sizes */ 4119906d46d4SStefano Zampini PetscInt global_size,local_size; 4120906d46d4SStefano Zampini /* temporary change of basis */ 4121906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 4122cf5a6209SStefano Zampini /* extra space for debugging */ 4123cf5a6209SStefano Zampini PetscScalar *dbg_work; 4124984c4197SStefano Zampini 4125906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 4126906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 412716f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 4128bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 4129906d46d4SStefano Zampini /* nonzeros for local mat */ 4130bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 41311dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4132bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 41331dd7afcfSStefano Zampini } else { 41341dd7afcfSStefano Zampini const PetscInt *ii; 41351dd7afcfSStefano Zampini PetscInt n; 41361dd7afcfSStefano Zampini PetscBool flg_row; 41371dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 41381dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 41391dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 41401dd7afcfSStefano Zampini } 41419162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 4142a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 41439162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 4144a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 41459162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 4146a717540cSStefano Zampini } else { 41479162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 41489162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 4149a717540cSStefano Zampini } 4150a717540cSStefano Zampini } 4151a717540cSStefano Zampini } 4152906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 4153bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 41541dd7afcfSStefano Zampini /* Set interior change in the matrix */ 41551dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 4156bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 4157906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 4158a717540cSStefano Zampini } 41591dd7afcfSStefano Zampini } else { 41601dd7afcfSStefano Zampini const PetscInt *ii,*jj; 41611dd7afcfSStefano Zampini PetscScalar *aa; 41621dd7afcfSStefano Zampini PetscInt n; 41631dd7afcfSStefano Zampini PetscBool flg_row; 41641dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 41651dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 41661dd7afcfSStefano Zampini for (i=0;i<n;i++) { 41671dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 41681dd7afcfSStefano Zampini } 41691dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 41701dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 41711dd7afcfSStefano Zampini } 4172a717540cSStefano Zampini 4173a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4174a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4175a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4176a717540cSStefano Zampini } 4177a717540cSStefano Zampini 4178a717540cSStefano Zampini 4179a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 4180a717540cSStefano Zampini /* 4181a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 4182a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 4183a717540cSStefano Zampini 4184a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 4185a717540cSStefano Zampini 4186a6b551f4SStefano 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) 4187a6b551f4SStefano Zampini 4188a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 4189a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 4190a717540cSStefano Zampini | ... | 4191a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 4192a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 4193a717540cSStefano Zampini 4194a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 4195a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 4196a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 4197a6b551f4SStefano Zampini 4198a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 4199a717540cSStefano Zampini */ 4200a717540cSStefano Zampini if (qr_needed) { 4201984c4197SStefano Zampini /* space to store Q */ 4202854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 4203984c4197SStefano Zampini /* first we issue queries for optimal work */ 42043f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 42053f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 42063f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4207984c4197SStefano Zampini lqr_work = -1; 42083f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 4209984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 4210984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 4211785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 4212984c4197SStefano Zampini lgqr_work = -1; 42133f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 42143f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 42153f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 42163f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 42173f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 42183f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 4219984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 4220984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 4221785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 4222984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 4223785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 4224984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 4225785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 4226a717540cSStefano Zampini /* allocating workspace for check */ 4227a717540cSStefano Zampini if (pcbddc->dbg_flag) { 4228cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 4229a717540cSStefano Zampini } 4230a717540cSStefano Zampini } 4231984c4197SStefano Zampini /* array to store whether a node is primal or not */ 42324641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 4233473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 42340e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 42356c4ed002SBarry 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); 423639e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 423739e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 423839e2fb2aSStefano Zampini } 423939e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 4240984c4197SStefano Zampini 4241a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 42429162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 42439162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 42444641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 4245984c4197SStefano Zampini /* get constraint info */ 42469162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 4247984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 4248984c4197SStefano Zampini 4249984c4197SStefano Zampini if (pcbddc->dbg_flag) { 42509162d606SStefano 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); 4251674ae819SStefano Zampini } 4252984c4197SStefano Zampini 4253fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 4254a717540cSStefano Zampini 4255a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 4256a717540cSStefano Zampini if (pcbddc->dbg_flag) { 42579162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4258a717540cSStefano Zampini } 4259984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 42609162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4261984c4197SStefano Zampini 4262984c4197SStefano Zampini /* compute QR decomposition of constraints */ 42633f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 42643f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 42653f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4266674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 42673f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 4268984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 4269674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4270984c4197SStefano Zampini 4271984c4197SStefano Zampini /* explictly compute R^-T */ 4272984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 4273984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 42743f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 42753f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 42763f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 42773f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 4278984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 42793f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 4280984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 4281984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4282984c4197SStefano Zampini 4283a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 42843f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 42853f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 42863f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 42873f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4288984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 42893f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 4290984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 4291984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4292984c4197SStefano Zampini 4293984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 4294984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 4295984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 42963f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 42973f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 42983f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 42993f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 43003f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 43013f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 4302984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 43039162d606SStefano 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)); 4304984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 43059162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 4306984c4197SStefano Zampini 4307984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 43089162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 4309984c4197SStefano Zampini /* insert cols for primal dofs */ 4310984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 4311984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 43129162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4313906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4314984c4197SStefano Zampini } 4315984c4197SStefano Zampini /* insert cols for dual dofs */ 4316984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 43179162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 4318984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 43199162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4320906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 4321984c4197SStefano Zampini j++; 4322674ae819SStefano Zampini } 4323674ae819SStefano Zampini } 4324984c4197SStefano Zampini 4325984c4197SStefano Zampini /* check change of basis */ 4326984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4327984c4197SStefano Zampini PetscInt ii,jj; 4328984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 4329c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 4330c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4331c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 4332c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4333c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 4334c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 4335984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4336cf5a6209SStefano 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)); 4337984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4338984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4339984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4340cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 4341cf5a6209SStefano 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; 4342674ae819SStefano Zampini } 4343674ae819SStefano Zampini } 4344984c4197SStefano Zampini if (!valid_qr) { 434522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 4346984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 4347984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 4348cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 4349cf5a6209SStefano 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])); 4350674ae819SStefano Zampini } 4351cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 4352cf5a6209SStefano 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])); 4353984c4197SStefano Zampini } 4354984c4197SStefano Zampini } 4355984c4197SStefano Zampini } 4356674ae819SStefano Zampini } else { 435722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 4358674ae819SStefano Zampini } 4359674ae819SStefano Zampini } 4360a717540cSStefano Zampini } else { /* simple transformation block */ 4361a717540cSStefano Zampini PetscInt row,col; 4362a6b551f4SStefano Zampini PetscScalar val,norm; 4363a6b551f4SStefano Zampini 4364a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 43659162d606SStefano 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)); 4366a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 43679162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 43689162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 4369bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 43709162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 4371906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 43729162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 4373a717540cSStefano Zampini } else { 4374a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 43759162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 4376a717540cSStefano Zampini if (row != col) { 43779162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 4378a717540cSStefano Zampini } else { 43799162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 4380a717540cSStefano Zampini } 4381906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 4382a717540cSStefano Zampini } 4383a717540cSStefano Zampini } 4384a717540cSStefano Zampini } 438598a51de6SStefano Zampini if (pcbddc->dbg_flag) { 438622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 4387a717540cSStefano Zampini } 4388674ae819SStefano Zampini } 4389984c4197SStefano Zampini } else { 4390984c4197SStefano Zampini if (pcbddc->dbg_flag) { 43919162d606SStefano 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); 4392674ae819SStefano Zampini } 4393674ae819SStefano Zampini } 4394674ae819SStefano Zampini } 4395a717540cSStefano Zampini 4396a717540cSStefano Zampini /* free workspace */ 4397a717540cSStefano Zampini if (qr_needed) { 4398984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4399cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 4400984c4197SStefano Zampini } 4401984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 4402984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 4403984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 4404984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 4405984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 4406674ae819SStefano Zampini } 4407a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 4408906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4409906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4410906d46d4SStefano Zampini 4411906d46d4SStefano Zampini /* assembling of global change of variable */ 441288c03ad3SStefano Zampini if (!pcbddc->fake_change) { 4413bbb9e6c6SStefano Zampini Mat tmat; 441416f15bc4SStefano Zampini PetscInt bs; 441516f15bc4SStefano Zampini 4416906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4417906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4418bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4419bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 4420bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4421bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 442216f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 442316f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 4424906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4425bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 4426bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4427bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4428bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4429bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4430e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4431e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4432bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 4433bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 443488c03ad3SStefano Zampini 4435906d46d4SStefano Zampini /* check */ 4436906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4437906d46d4SStefano Zampini PetscReal error; 4438906d46d4SStefano Zampini Vec x,x_change; 4439906d46d4SStefano Zampini 4440906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 4441906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 4442906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 4443906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 4444e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4445e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4446bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4447e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4448e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4449906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4450906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4451906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4452906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4453bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4454906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4455906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4456906d46d4SStefano Zampini } 4457b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4458b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4459b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4460bf3a8328SStefano Zampini 4461bf3a8328SStefano Zampini if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) { 4462bf3a8328SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints");CHKERRQ(ierr); 4463bf3a8328SStefano Zampini } 4464b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 4465ac632422SStefano Zampini Mat S_new,tmat; 4466bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 4467bbb9e6c6SStefano Zampini 4468bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 44696816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4470bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4471bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 4472bf3a8328SStefano Zampini IS is_V; 4473b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4474b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4475b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4476b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4477b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4478bf3a8328SStefano Zampini } 4479bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4480ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4481b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4482ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4483bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4484bf3a8328SStefano Zampini const PetscScalar *array; 4485bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 4486bf3a8328SStefano Zampini PetscInt i,n_V; 4487bf3a8328SStefano Zampini 4488b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4489b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4490b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4491b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4492b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4493b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4494b087196eSStefano Zampini PetscScalar val; 4495b087196eSStefano Zampini PetscInt idx; 4496b087196eSStefano Zampini 4497b087196eSStefano Zampini idx = idxs_V[i]; 4498b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4499b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4500b087196eSStefano Zampini } 4501b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4502b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4503bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4504bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4505bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4506bf3a8328SStefano Zampini } 4507ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4508ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4509ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4510ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4511b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4512ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4513bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 4514b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4515bf3a8328SStefano Zampini } 4516ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4517ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4518ac632422SStefano Zampini } 4519b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 452088c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4521b96c3477SStefano Zampini } 4522c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 4523c9db6a07SStefano Zampini if (sub_schurs->change) { 4524c9db6a07SStefano Zampini PetscInt i; 4525c9db6a07SStefano Zampini 4526c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4527c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 4528c9db6a07SStefano Zampini } 4529c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 4530c9db6a07SStefano Zampini } 4531b96c3477SStefano Zampini } 453216909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 453316909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 453416909a7fSStefano Zampini } else { 4535906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 453616909a7fSStefano Zampini } 45371dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 453827b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 453972b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 454072b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 454172b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 454272b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 454372b8c272SStefano Zampini } 45441dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 454527b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 4546b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4547b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4548906d46d4SStefano Zampini } else { 45491dd7afcfSStefano Zampini Mat benign_global = NULL; 455027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 45511dd7afcfSStefano Zampini Mat tmat; 45521dd7afcfSStefano Zampini 45531dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 45541dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 45551dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 45561dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 45571dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 45581dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 45591dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 45601dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 45611dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 45621dd7afcfSStefano Zampini if (pcbddc->benign_change) { 45631dd7afcfSStefano Zampini Mat M; 45641dd7afcfSStefano Zampini 45651dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 45661dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 45671dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 45681dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4569906d46d4SStefano Zampini } else { 45701dd7afcfSStefano Zampini Mat eye; 45711dd7afcfSStefano Zampini PetscScalar *array; 45721dd7afcfSStefano Zampini 45731dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 45741dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 45751dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 45761dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 4577906d46d4SStefano Zampini } 45781dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 45791dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45801dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45811dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 45821dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 45831dd7afcfSStefano Zampini } 45841dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 45851dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 45861dd7afcfSStefano Zampini } 45871dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 45881dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 45891dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 459027b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 45911dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 45921dd7afcfSStefano Zampini } 45931dd7afcfSStefano Zampini } 459416909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 459516909a7fSStefano Zampini IS is_global; 459616909a7fSStefano Zampini const PetscInt *gidxs; 459716909a7fSStefano Zampini 459816909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 459916909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 460016909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 460116909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 460216909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 460316909a7fSStefano Zampini } 46041dd7afcfSStefano Zampini } 46051dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 46061dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 4607b9b85e73SStefano Zampini } 4608a717540cSStefano Zampini 460972b8c272SStefano Zampini if (!pcbddc->fake_change) { 46104f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 46114f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 46124f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 46134f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4614019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4615019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4616019a44ceSStefano Zampini pcbddc->local_primal_size++; 4617019a44ceSStefano Zampini } 4618019a44ceSStefano Zampini 4619019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4620727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4621727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 46229f47a83aSStefano 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); 4623c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 46240e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 46259f47a83aSStefano 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); 4626727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4627727cdba6SStefano Zampini } 46280e6343abSStefano Zampini } 4629727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4630b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 463172b8c272SStefano Zampini } 463272b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4633727cdba6SStefano Zampini 4634a717540cSStefano Zampini /* flush dbg viewer */ 4635b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4636b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4637b8ffe317SStefano Zampini } 4638a717540cSStefano Zampini 4639e310c8b4SStefano Zampini /* free workspace */ 4640a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 46414641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 464208122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 46439162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 46449162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 464508122e43SStefano Zampini } else { 46469162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 46479162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 46489162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 464908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 465008122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 46519162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 46529162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 465308122e43SStefano Zampini } 4654674ae819SStefano Zampini PetscFunctionReturn(0); 4655674ae819SStefano Zampini } 4656674ae819SStefano Zampini 4657674ae819SStefano Zampini #undef __FUNCT__ 4658674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4659674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4660674ae819SStefano Zampini { 4661674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4662674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4663674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 466414f95afaSStefano Zampini PetscInt ierr,i,N; 4665674ae819SStefano Zampini 4666674ae819SStefano Zampini PetscFunctionBegin; 46678e61c736SStefano Zampini /* Reset previously computed graph */ 46688e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4669674ae819SStefano Zampini /* Init local Graph struct */ 46707fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 46713bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4672674ae819SStefano Zampini 4673575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 46745099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 46755099eff2SStefano 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); 4676575ad6abSStefano Zampini } 46779577ea80SStefano Zampini 4678674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 4679d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 46804d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 46814d379d7bSStefano Zampini PetscInt nvtxs; 4682e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4683674ae819SStefano Zampini 46842fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 46852fffb893SStefano Zampini if (flg_row) { 46864d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4687b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 46882fffb893SStefano Zampini } 46892fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4690674ae819SStefano Zampini } 46919b28b941SStefano Zampini if (pcbddc->dbg_flag) { 46929b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4693674ae819SStefano Zampini } 4694674ae819SStefano Zampini 4695674ae819SStefano Zampini /* Setup of Graph */ 469614f95afaSStefano 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); 4697674ae819SStefano Zampini 46984f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 46994f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 47004f1b2e48SStefano Zampini PetscInt *local_subs; 47014f1b2e48SStefano Zampini 47024f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 47034f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 47044f1b2e48SStefano Zampini const PetscInt *idxs; 47054f1b2e48SStefano Zampini PetscInt nl,j; 47064f1b2e48SStefano Zampini 47074f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 47084f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 47094f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 47104f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 47114f1b2e48SStefano Zampini } 47124f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 47134f1b2e48SStefano Zampini } 47144f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 47154f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 47164f1b2e48SStefano Zampini } 47174f1b2e48SStefano Zampini 4718674ae819SStefano Zampini /* Graph's connected components analysis */ 4719674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4720674ae819SStefano Zampini PetscFunctionReturn(0); 4721674ae819SStefano Zampini } 4722674ae819SStefano Zampini 4723dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 4724674ae819SStefano Zampini #undef __FUNCT__ 4725674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 4726dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 4727674ae819SStefano Zampini { 4728dc456d91SStefano Zampini PetscSF sf; 4729dc456d91SStefano Zampini PetscLayout map; 4730dc456d91SStefano Zampini const PetscInt *idxs; 4731dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4732dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4733dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4734dc456d91SStefano Zampini PetscMPIInt commsize; 4735674ae819SStefano Zampini PetscBool first_found; 4736674ae819SStefano Zampini PetscErrorCode ierr; 4737674ae819SStefano Zampini 4738674ae819SStefano Zampini PetscFunctionBegin; 4739dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4740dc456d91SStefano Zampini if (subset_mult) { 4741dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4742dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4743dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4744674ae819SStefano Zampini } 4745dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4746dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4747dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4748dc456d91SStefano Zampini for (i=0;i<n;i++) { 4749dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4750dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4751674ae819SStefano Zampini } 4752dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4753b2566f29SBarry Smith ierr = MPIU_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4754dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4755dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4756dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4757dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4758dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4759dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4760dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4761dc456d91SStefano Zampini 4762dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4763dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4764dc456d91SStefano Zampini if (subset_mult) { 4765dc456d91SStefano Zampini const PetscInt* idxs_mult; 4766dc456d91SStefano Zampini 4767dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4768dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4769dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4770674ae819SStefano Zampini } else { 4771dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4772674ae819SStefano Zampini } 4773dc456d91SStefano Zampini /* local size of new subset */ 4774dc456d91SStefano Zampini n_n = 0; 4775dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4776dc456d91SStefano Zampini 4777dc456d91SStefano Zampini /* global indexes in layout */ 4778dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4779dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4780dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4781dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4782dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4783dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4784dc456d91SStefano Zampini 4785dc456d91SStefano Zampini /* reduce from leaves to roots */ 4786dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 478764a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 478864a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4789dc456d91SStefano Zampini 4790dc456d91SStefano Zampini /* count indexes in local part of layout */ 4791674ae819SStefano Zampini nlocals = 0; 4792674ae819SStefano Zampini first_index = -1; 4793674ae819SStefano Zampini first_found = PETSC_FALSE; 4794dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4795dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4796674ae819SStefano Zampini first_found = PETSC_TRUE; 4797674ae819SStefano Zampini first_index = i; 4798674ae819SStefano Zampini } 4799dc456d91SStefano Zampini nlocals += root_data[i]; 4800674ae819SStefano Zampini } 4801dc456d91SStefano Zampini 4802dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 48035fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4804dc456d91SStefano Zampini start = 0; 480564a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 48065fa240b1SStefano Zampini #else 480764a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 48085fa240b1SStefano Zampini start = start-nlocals; 48095fa240b1SStefano Zampini #endif 48105fa240b1SStefano Zampini 4811dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4812dc456d91SStefano Zampini *N_n = start + nlocals; 4813dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4814dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4815674ae819SStefano Zampini } 48165fa240b1SStefano Zampini 48175fa240b1SStefano Zampini /* adapt root data with cumulative */ 4818674ae819SStefano Zampini if (first_found) { 4819dc456d91SStefano Zampini PetscInt old_index; 4820dc456d91SStefano Zampini 4821dc456d91SStefano Zampini root_data[first_index] += start; 4822674ae819SStefano Zampini old_index = first_index; 4823dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4824dc456d91SStefano Zampini if (root_data[i]) { 4825dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4826674ae819SStefano Zampini old_index = i; 4827674ae819SStefano Zampini } 4828674ae819SStefano Zampini } 4829674ae819SStefano Zampini } 4830dc456d91SStefano Zampini 4831dc456d91SStefano Zampini /* from roots to leaves */ 4832dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4833dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4834dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4835dc456d91SStefano Zampini 4836dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4837dc456d91SStefano Zampini if (subset_mult) { 4838dc456d91SStefano Zampini const PetscInt* idxs_mult; 4839dc456d91SStefano Zampini PetscInt cum; 4840dc456d91SStefano Zampini 4841dc456d91SStefano Zampini cum = 0; 4842dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4843dc456d91SStefano Zampini for (i=0;i<n;i++) { 4844dc456d91SStefano Zampini PetscInt j; 4845dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4846674ae819SStefano Zampini } 4847dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4848674ae819SStefano Zampini } else { 4849dc456d91SStefano Zampini for (i=0;i<n;i++) { 4850dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4851674ae819SStefano Zampini } 4852674ae819SStefano Zampini } 4853dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4854dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4855674ae819SStefano Zampini PetscFunctionReturn(0); 4856674ae819SStefano Zampini } 48579a7d3425SStefano Zampini 48589a7d3425SStefano Zampini #undef __FUNCT__ 48599a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 48609a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 48619a7d3425SStefano Zampini { 48629a7d3425SStefano Zampini PetscInt i,j; 48639a7d3425SStefano Zampini PetscScalar *alphas; 48649a7d3425SStefano Zampini PetscErrorCode ierr; 48659a7d3425SStefano Zampini 48669a7d3425SStefano Zampini PetscFunctionBegin; 48679a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4868785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 48699a7d3425SStefano Zampini for (i=0;i<n;i++) { 48709a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 48719a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 48729a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 48739a7d3425SStefano Zampini } 48749a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 48759a7d3425SStefano Zampini PetscFunctionReturn(0); 48769a7d3425SStefano Zampini } 48779a7d3425SStefano Zampini 4878e7931f94SStefano Zampini #undef __FUNCT__ 487970cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 488057de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 4881e7931f94SStefano Zampini { 488257de7509SStefano Zampini Mat A; 4883e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4884e7931f94SStefano Zampini PetscMPIInt size,rank,color; 488552e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 488652e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 488727b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 488857de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 488927b6a85dSStefano Zampini PetscInt xadj_count, *count; 489027b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 489127b6a85dSStefano Zampini PetscSubcomm psubcomm; 489227b6a85dSStefano Zampini MPI_Comm subcomm; 489352e5ac9dSStefano Zampini PetscErrorCode ierr; 4894a57a6d2fSStefano Zampini 4895e7931f94SStefano Zampini PetscFunctionBegin; 489657de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 489757de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 489857de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 489957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 490057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 490157de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 490257de7509SStefano Zampini 490357de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 490457de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 490557de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 490657de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 490757de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 490857de7509SStefano Zampini im_active = !!(n); 490957de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 491057de7509SStefano Zampini void_procs = size - active_procs; 491157de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 491257de7509SStefano Zampini if (void_procs) { 491357de7509SStefano Zampini PetscInt ncand; 491457de7509SStefano Zampini 491557de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 491657de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 491757de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 491857de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 491957de7509SStefano Zampini if (!procs_candidates[i]) { 492057de7509SStefano Zampini procs_candidates[ncand++] = i; 492157de7509SStefano Zampini } 492257de7509SStefano Zampini } 492357de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 492457de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 492557de7509SStefano Zampini } 492657de7509SStefano Zampini 492757de7509SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix */ 492857de7509SStefano Zampini if (active_procs < *n_subdomains) { 492957de7509SStefano Zampini PetscInt issize,isidx; 493057de7509SStefano Zampini if (im_active) { 493157de7509SStefano Zampini issize = 1; 493257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 493357de7509SStefano Zampini isidx = procs_candidates[rank]; 493457de7509SStefano Zampini } else { 493557de7509SStefano Zampini isidx = rank; 493657de7509SStefano Zampini } 493757de7509SStefano Zampini } else { 493857de7509SStefano Zampini issize = 0; 493957de7509SStefano Zampini isidx = -1; 494057de7509SStefano Zampini } 494157de7509SStefano Zampini *n_subdomains = active_procs; 494257de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 4943daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 494457de7509SStefano Zampini PetscFunctionReturn(0); 494557de7509SStefano Zampini } 4946c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 4947c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 494827b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 4949e7931f94SStefano Zampini 4950e7931f94SStefano Zampini /* Get info on mapping */ 49513bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 49523bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4953e7931f94SStefano Zampini 4954e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4955785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4956e7931f94SStefano Zampini xadj[0] = 0; 4957e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4958785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4959785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 496027b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 496127b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 496227b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 496327b6a85dSStefano Zampini count[shared[i][j]] += 1; 4964e7931f94SStefano Zampini 496527b6a85dSStefano Zampini xadj_count = 0; 49662b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 496727b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 496827b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 4969d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4970d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4971d023bfaeSStefano Zampini xadj_count++; 497227b6a85dSStefano Zampini break; 497327b6a85dSStefano Zampini } 4974e7931f94SStefano Zampini } 4975e7931f94SStefano Zampini } 4976d023bfaeSStefano Zampini xadj[1] = xadj_count; 497727b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 49783bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4979e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4980e7931f94SStefano Zampini 49813837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4982e7931f94SStefano Zampini 498327b6a85dSStefano Zampini /* Restrict work on active processes only */ 498427b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 498527b6a85dSStefano Zampini if (void_procs) { 498627b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 498727b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 498827b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 498927b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 499027b6a85dSStefano Zampini } else { 499127b6a85dSStefano Zampini psubcomm = NULL; 499227b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 499327b6a85dSStefano Zampini } 499427b6a85dSStefano Zampini 499527b6a85dSStefano Zampini v_wgt = NULL; 499627b6a85dSStefano Zampini if (!color) { 4997e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4998e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4999e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5000c8587f34SStefano Zampini } else { 500152e5ac9dSStefano Zampini Mat subdomain_adj; 500252e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 500352e5ac9dSStefano Zampini MatPartitioning partitioner; 500427b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 500552e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 500657de7509SStefano Zampini PetscMPIInt size; 5007b0c7d250SStefano Zampini PetscBool aggregate; 5008b0c7d250SStefano Zampini 500927b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 501027b6a85dSStefano Zampini if (void_procs) { 501127b6a85dSStefano Zampini PetscInt prank = rank; 5012785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 501327b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 5014e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 5015e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 5016c8587f34SStefano Zampini } 5017e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 501827b6a85dSStefano Zampini } else { 501927b6a85dSStefano Zampini oldranks = NULL; 502027b6a85dSStefano Zampini } 5021b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 502227b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 5023b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 5024b0c7d250SStefano Zampini PetscMPIInt nrank; 5025b0c7d250SStefano Zampini PetscScalar *vals; 5026b0c7d250SStefano Zampini 502727b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 5028b0c7d250SStefano Zampini lrows = 0; 5029b0c7d250SStefano Zampini if (nrank<redprocs) { 5030b0c7d250SStefano Zampini lrows = size/redprocs; 5031b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 5032b0c7d250SStefano Zampini } 503327b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 5034b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 5035b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5036b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5037b0c7d250SStefano Zampini row = nrank; 5038b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 5039b0c7d250SStefano Zampini cols = adjncy; 5040b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 5041b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 5042b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 5043b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5044b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 504552e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 504652e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 504752e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5048b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 504927b6a85dSStefano Zampini if (use_vwgt) { 505027b6a85dSStefano Zampini Vec v; 505127b6a85dSStefano Zampini const PetscScalar *array; 505227b6a85dSStefano Zampini PetscInt nl; 505327b6a85dSStefano Zampini 505427b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 505527b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 505627b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 505727b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 505827b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 505927b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 506027b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 506122db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 506227b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 506327b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 506427b6a85dSStefano Zampini } 5065b0c7d250SStefano Zampini } else { 506627b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 506727b6a85dSStefano Zampini if (use_vwgt) { 506827b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 506927b6a85dSStefano Zampini v_wgt[0] = local_size; 507027b6a85dSStefano Zampini } 5071b0c7d250SStefano Zampini } 507222b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 5073e7931f94SStefano Zampini 5074e7931f94SStefano Zampini /* Partition */ 507527b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 5076e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 507727b6a85dSStefano Zampini if (v_wgt) { 5078e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 5079c8587f34SStefano Zampini } 508057de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 508157de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 5082e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 5083e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 508422b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 5085e7931f94SStefano Zampini 508652e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 508752e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 508852e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 508952e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 509057de7509SStefano Zampini if (!aggregate) { 509157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 509227b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 509327b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 509427b6a85dSStefano Zampini #endif 509557de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 509627b6a85dSStefano Zampini } else if (oldranks) { 5097b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 509827b6a85dSStefano Zampini } else { 509927b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 510057de7509SStefano Zampini } 510128143c3dSStefano Zampini } else { 5102b0c7d250SStefano Zampini PetscInt idxs[1]; 5103b0c7d250SStefano Zampini PetscMPIInt tag; 5104b0c7d250SStefano Zampini MPI_Request *reqs; 5105b0c7d250SStefano Zampini 5106b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 5107b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 5108b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 510927b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 511028143c3dSStefano Zampini } 511127b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 5112b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5113b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 511457de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 511527b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 511627b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 511727b6a85dSStefano Zampini #endif 511857de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 511927b6a85dSStefano Zampini } else if (oldranks) { 5120b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 512127b6a85dSStefano Zampini } else { 512227b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 5123e7931f94SStefano Zampini } 512457de7509SStefano Zampini } 512552e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5126e7931f94SStefano Zampini /* clean up */ 5127e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 512852e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 5129e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 5130e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 5131e7931f94SStefano Zampini } 513227b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 513357de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 5134e7931f94SStefano Zampini 5135e7931f94SStefano Zampini /* assemble parallel IS for sends */ 5136e7931f94SStefano Zampini i = 1; 513727b6a85dSStefano Zampini if (!color) i=0; 513857de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 5139e7931f94SStefano Zampini PetscFunctionReturn(0); 5140e7931f94SStefano Zampini } 5141e7931f94SStefano Zampini 5142e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 5143e7931f94SStefano Zampini 5144e7931f94SStefano Zampini #undef __FUNCT__ 5145e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 514657de7509SStefano 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[]) 5147e7931f94SStefano Zampini { 514870cf5478SStefano Zampini Mat local_mat; 5149e7931f94SStefano Zampini IS is_sends_internal; 51509d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 515128143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 51529d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 5153e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 5154e7931f94SStefano Zampini PetscInt* l2gmap_indices; 5155e7931f94SStefano Zampini const PetscInt* is_indices; 5156e7931f94SStefano Zampini MatType new_local_type; 5157e7931f94SStefano Zampini /* buffers */ 5158e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 515928143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 51609d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 5161e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 5162e7931f94SStefano Zampini /* MPI */ 516328143c3dSStefano Zampini MPI_Comm comm,comm_n; 516428143c3dSStefano Zampini PetscSubcomm subcomm; 5165e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 516628143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 516728143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 516828143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 516928143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 517028143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 5171e7931f94SStefano Zampini PetscErrorCode ierr; 5172e7931f94SStefano Zampini 5173e7931f94SStefano Zampini PetscFunctionBegin; 517457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5175e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 517628143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 517757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 517857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 517957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 518057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 518157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 518257de7509SStefano Zampini 518357de7509SStefano Zampini /* further checks */ 5184e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5185e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 5186e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 5187e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 5188e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 518957de7509SStefano Zampini if (reuse && *mat_n) { 519070cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 519157de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 519270cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 519328143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 519470cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 519570cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 519670cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 519770cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 519870cf5478SStefano Zampini } 5199e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 5200e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 520157de7509SStefano Zampini 5202e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 5203e7931f94SStefano Zampini if (!is_sends) { 520428143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 520557de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 5206c8587f34SStefano Zampini } else { 5207e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 5208e7931f94SStefano Zampini is_sends_internal = is_sends; 5209c8587f34SStefano Zampini } 5210e7931f94SStefano Zampini 5211e7931f94SStefano Zampini /* get comm */ 5212a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 5213e7931f94SStefano Zampini 5214e7931f94SStefano Zampini /* compute number of sends */ 5215e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 5216e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 5217e7931f94SStefano Zampini 5218e7931f94SStefano Zampini /* compute number of receives */ 5219e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 5220785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 5221e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 5222e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5223e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 5224e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 5225e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 5226e7931f94SStefano Zampini 522728143c3dSStefano Zampini /* restrict comm if requested */ 522828143c3dSStefano Zampini subcomm = 0; 522928143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 523028143c3dSStefano Zampini if (restrict_comm) { 5231779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 5232779c1cceSStefano Zampini 523328143c3dSStefano Zampini color = 0; 523453a05cb3SStefano Zampini if (restrict_full) { 523553a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 523653a05cb3SStefano Zampini } else { 523753a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 523853a05cb3SStefano Zampini } 5239b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 524028143c3dSStefano Zampini subcommsize = commsize - subcommsize; 524128143c3dSStefano Zampini /* check if reuse has been requested */ 524257de7509SStefano Zampini if (reuse) { 524328143c3dSStefano Zampini if (*mat_n) { 524428143c3dSStefano Zampini PetscMPIInt subcommsize2; 524528143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 524628143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 524728143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 524828143c3dSStefano Zampini } else { 524928143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 525028143c3dSStefano Zampini } 525128143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 5252779c1cceSStefano Zampini PetscMPIInt rank; 5253779c1cceSStefano Zampini 5254779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 525528143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 525628143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 525728143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 5258306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 525928143c3dSStefano Zampini } 526028143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 526128143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 526228143c3dSStefano Zampini } else { 526328143c3dSStefano Zampini comm_n = comm; 526428143c3dSStefano Zampini } 526528143c3dSStefano Zampini 5266e7931f94SStefano Zampini /* prepare send/receive buffers */ 5267785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 5268e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 5269785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 5270e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 527128143c3dSStefano Zampini if (nis) { 5272854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 527328143c3dSStefano Zampini } 5274e7931f94SStefano Zampini 527528143c3dSStefano Zampini /* Get data from local matrices */ 52766c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 5277e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 5278e7931f94SStefano Zampini /* 5279e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 5280e7931f94SStefano Zampini send_buffer_idxs should contain: 5281e7931f94SStefano Zampini - MatType_PRIVATE type 5282e7931f94SStefano Zampini - PetscInt size_of_l2gmap 5283e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 5284e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 5285e7931f94SStefano Zampini */ 52866c4ed002SBarry Smith else { 5287e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 52883bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 5289854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 5290e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 5291e7931f94SStefano Zampini send_buffer_idxs[1] = i; 52923bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5293e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 52943bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 5295e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 5296e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5297e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 5298e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 5299c8587f34SStefano Zampini } 5300c8587f34SStefano Zampini } 5301e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 530228143c3dSStefano Zampini /* additional is (if any) */ 530328143c3dSStefano Zampini if (nis) { 530428143c3dSStefano Zampini PetscMPIInt psum; 530528143c3dSStefano Zampini PetscInt j; 530628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 530728143c3dSStefano Zampini PetscInt plen; 530828143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 530928143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 531028143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 531128143c3dSStefano Zampini } 5312854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 531328143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 531428143c3dSStefano Zampini PetscInt plen; 531528143c3dSStefano Zampini const PetscInt *is_array_idxs; 531628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 531728143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 531828143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 531928143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 532028143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 532128143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 532228143c3dSStefano Zampini } 532328143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 532428143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 532528143c3dSStefano Zampini } 532628143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 532728143c3dSStefano Zampini } 532828143c3dSStefano Zampini 5329e7931f94SStefano Zampini buf_size_idxs = 0; 5330e7931f94SStefano Zampini buf_size_vals = 0; 533128143c3dSStefano Zampini buf_size_idxs_is = 0; 5332e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5333e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 5334e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 533528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 5336e7931f94SStefano Zampini } 5337785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 5338785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 533995ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 5340e7931f94SStefano Zampini 5341e7931f94SStefano Zampini /* get new tags for clean communications */ 5342e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 5343e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 534428143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 5345e7931f94SStefano Zampini 5346e7931f94SStefano Zampini /* allocate for requests */ 5347785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 5348785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 534995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 5350785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 5351785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 535295ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 5353e7931f94SStefano Zampini 5354e7931f94SStefano Zampini /* communications */ 5355e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5356e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 535728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 5358e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5359e7931f94SStefano Zampini source_dest = onodes[i]; 5360e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 5361e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 5362e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5363e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 536428143c3dSStefano Zampini if (nis) { 536557de7509SStefano Zampini source_dest = onodes_is[i]; 536628143c3dSStefano 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); 536728143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 536828143c3dSStefano Zampini } 5369e7931f94SStefano Zampini } 5370e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 5371e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 5372e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 5373e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 537428143c3dSStefano Zampini if (nis) { 537528143c3dSStefano 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); 537628143c3dSStefano Zampini } 5377e7931f94SStefano Zampini } 5378e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 5379e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 5380e7931f94SStefano Zampini 5381e7931f94SStefano Zampini /* assemble new l2g map */ 5382e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5383e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 53849d30be91SStefano Zampini new_local_rows = 0; 5385e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 53869d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5387e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5388e7931f94SStefano Zampini } 53899d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 5390e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 53919d30be91SStefano Zampini new_local_rows = 0; 5392e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 53939d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 53949d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 5395e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5396e7931f94SStefano Zampini } 53979d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 53989d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 5399e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 5400e7931f94SStefano Zampini 5401e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 5402e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 5403e7931f94SStefano 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) */ 5404e7931f94SStefano Zampini if (n_recvs) { 540528143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 5406e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 5407e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5408e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 5409e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 5410e7931f94SStefano Zampini break; 5411e7931f94SStefano Zampini } 5412e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5413e7931f94SStefano Zampini } 5414e7931f94SStefano Zampini switch (new_local_type_private) { 541528143c3dSStefano Zampini case MATDENSE_PRIVATE: 541628143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 5417e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5418e7931f94SStefano Zampini bs = 1; 541928143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 542028143c3dSStefano Zampini new_local_type = MATSEQDENSE; 542128143c3dSStefano Zampini bs = 1; 542228143c3dSStefano Zampini } 5423e7931f94SStefano Zampini break; 5424e7931f94SStefano Zampini case MATAIJ_PRIVATE: 5425e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 5426e7931f94SStefano Zampini bs = 1; 5427e7931f94SStefano Zampini break; 5428e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 5429e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 5430e7931f94SStefano Zampini break; 5431e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 5432e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 5433e7931f94SStefano Zampini break; 5434e7931f94SStefano Zampini default: 54359d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 5436e7931f94SStefano Zampini break; 5437e7931f94SStefano Zampini } 543828143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 543928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 544028143c3dSStefano Zampini bs = 1; 5441e7931f94SStefano Zampini } 5442e7931f94SStefano Zampini 544370cf5478SStefano Zampini /* create MATIS object if needed */ 544457de7509SStefano Zampini if (!reuse) { 5445e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 5446e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 544770cf5478SStefano Zampini } else { 544870cf5478SStefano Zampini /* it also destroys the local matrices */ 544957de7509SStefano Zampini if (*mat_n) { 545070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 545157de7509SStefano Zampini } else { /* this is a fake object */ 545257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 545357de7509SStefano Zampini } 545470cf5478SStefano Zampini } 545570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 5456e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 54579d30be91SStefano Zampini 54589d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 54599d30be91SStefano Zampini 54609d30be91SStefano Zampini /* Global to local map of received indices */ 54619d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 54629d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 54639d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 54649d30be91SStefano Zampini 54659d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 54669d30be91SStefano Zampini buf_size_idxs = 0; 54679d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 54689d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 54699d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 54709d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 54719d30be91SStefano Zampini } 54729d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 54739d30be91SStefano Zampini 54749d30be91SStefano Zampini /* set preallocation */ 54759d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 54769d30be91SStefano Zampini if (!newisdense) { 54779d30be91SStefano Zampini PetscInt *new_local_nnz=0; 54789d30be91SStefano Zampini 54799d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 54809d30be91SStefano Zampini if (n_recvs) { 54819d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 54829d30be91SStefano Zampini } 54839d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 54849d30be91SStefano Zampini PetscInt j; 54859d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 54869d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 54879d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 54889d30be91SStefano Zampini } 54899d30be91SStefano Zampini } else { 54909d30be91SStefano Zampini /* TODO */ 54919d30be91SStefano Zampini } 54929d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 54939d30be91SStefano Zampini } 54949d30be91SStefano Zampini if (new_local_nnz) { 54959d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 54969d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 54979d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 54989d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 54999d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 55009d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 55019d30be91SStefano Zampini } else { 55029d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 55039d30be91SStefano Zampini } 55049d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 55059d30be91SStefano Zampini } else { 55069d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 55079d30be91SStefano Zampini } 5508e7931f94SStefano Zampini 5509e7931f94SStefano Zampini /* set values */ 5510e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 55119d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5512e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5513e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5514e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 55159d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5516e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5517e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5518e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 551928143c3dSStefano Zampini } else { 552028143c3dSStefano Zampini /* TODO */ 5521e7931f94SStefano Zampini } 5522e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5523e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5524e7931f94SStefano Zampini } 5525e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5526e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 552770cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 552870cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55299d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 55309d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5531e7931f94SStefano Zampini 5532dfd14d43SStefano Zampini #if 0 553328143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5534e7931f94SStefano Zampini Vec lvec,rvec; 5535e7931f94SStefano Zampini PetscReal infty_error; 5536e7931f94SStefano Zampini 55372a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5538e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5539e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5540e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 554170cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5542e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5543e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5544e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5545e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5546e7931f94SStefano Zampini } 554728143c3dSStefano Zampini #endif 5548e7931f94SStefano Zampini 554928143c3dSStefano Zampini /* assemble new additional is (if any) */ 555028143c3dSStefano Zampini if (nis) { 555128143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 555228143c3dSStefano Zampini 555328143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5554854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 555528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 555628143c3dSStefano Zampini psum = 0; 555728143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 555828143c3dSStefano Zampini for (j=0;j<nis;j++) { 555928143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 556028143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 556128143c3dSStefano Zampini psum += plen; 556228143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 556328143c3dSStefano Zampini } 556428143c3dSStefano Zampini } 5565854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5566854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 556728143c3dSStefano Zampini for (i=1;i<nis;i++) { 556828143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 556928143c3dSStefano Zampini } 557028143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 557128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 557228143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 557328143c3dSStefano Zampini for (j=0;j<nis;j++) { 557428143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 557528143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 557628143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 557728143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 557828143c3dSStefano Zampini } 557928143c3dSStefano Zampini } 558028143c3dSStefano Zampini for (i=0;i<nis;i++) { 558128143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 558228143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 558328143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 558428143c3dSStefano Zampini } 558528143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 558628143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 558728143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 558828143c3dSStefano Zampini } 5589e7931f94SStefano Zampini /* free workspace */ 559028143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5591e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5592e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5593e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5594e7931f94SStefano Zampini if (isdense) { 5595e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5596e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5597e7931f94SStefano Zampini } else { 5598e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5599e7931f94SStefano Zampini } 560028143c3dSStefano Zampini if (nis) { 560128143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 560228143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 560328143c3dSStefano Zampini } 5604e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5605e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 560628143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5607e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5608e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 560928143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5610e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5611e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5612e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5613e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5614e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 561528143c3dSStefano Zampini if (nis) { 561628143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 561728143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 561828143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 561928143c3dSStefano Zampini } 562028143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 562128143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 562228143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 562328143c3dSStefano Zampini for (i=0;i<nis;i++) { 562428143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 562528143c3dSStefano Zampini } 562653a05cb3SStefano Zampini *mat_n = NULL; 562728143c3dSStefano Zampini } 5628e7931f94SStefano Zampini PetscFunctionReturn(0); 5629e7931f94SStefano Zampini } 5630a57a6d2fSStefano Zampini 563112edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5632af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 563312edc857SStefano Zampini 5634c8587f34SStefano Zampini #undef __FUNCT__ 5635c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5636c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5637c8587f34SStefano Zampini { 5638c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5639c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 564020a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 56419881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 564220a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 56436e683305SStefano Zampini IS coarse_is,*isarray; 56446e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 564530368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5646f9eb5b7dSStefano Zampini PC pc_temp; 5647c8587f34SStefano Zampini PCType coarse_pc_type; 5648c8587f34SStefano Zampini KSPType coarse_ksp_type; 5649f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 56504f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 56516e683305SStefano Zampini Mat t_coarse_mat_is; 565257de7509SStefano Zampini PetscInt ncoarse; 565368457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 565422bc73bbSStefano Zampini PetscScalar *array; 565557de7509SStefano Zampini MatReuse coarse_mat_reuse; 565657de7509SStefano Zampini PetscBool restr, full_restr, have_void; 56579881197aSStefano Zampini PetscErrorCode ierr; 5658fdc09c96SStefano Zampini 5659c8587f34SStefano Zampini PetscFunctionBegin; 5660c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 566168457ee5SStefano 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 */ 5662fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 56635a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5664fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5665f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5666f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5667f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5668fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 566951bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 567051bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5671dc4bcba2SStefano Zampini PC pc; 5672dc4bcba2SStefano Zampini PetscBool isbddc; 5673dc4bcba2SStefano Zampini 5674dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5675dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5676dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5677dc4bcba2SStefano Zampini if (isbddc) { 567863c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 567963c961adSStefano Zampini } else { 5680727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 568163c961adSStefano Zampini } 5682fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5683fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5684fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5685f4ddd8eeSStefano Zampini } 5686fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5687fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5688f4ddd8eeSStefano Zampini } 568970cf5478SStefano Zampini /* reset any subassembling information */ 569057de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 569170cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 569257de7509SStefano Zampini } 56936e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5694fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5695f4ddd8eeSStefano Zampini } 569657de7509SStefano Zampini /* assemble coarse matrix */ 569757de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 569857de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 569957de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 570057de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 570118a45a71SStefano Zampini } else { 570257de7509SStefano Zampini coarse_mat = NULL; 570357de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 57046e683305SStefano Zampini } 5705e7931f94SStefano Zampini 5706abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5707abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5708abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5709abbbba34SStefano Zampini 5710abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 571122bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 571222bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 571322bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 571422bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5715e176bc59SStefano 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); 57166e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 57176e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 57186e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5719abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5720abbbba34SStefano Zampini 572157de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 572257de7509SStefano Zampini im_active = !!(pcis->n); 572357de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 572457de7509SStefano Zampini 572557de7509SStefano Zampini /* determine number of process partecipating to coarse solver and compute subassembling pattern */ 572657de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 572757de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 572857de7509SStefano Zampini coarse_mat_is = NULL; 572957de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 573057de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 573157de7509SStefano Zampini full_restr = PETSC_TRUE; 573257de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(pcbddc->coarse_size,pcbddc->coarse_eqs_per_proc); 573357de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 573457de7509SStefano Zampini if (multilevel_requested) { 573557de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 573657de7509SStefano Zampini restr = PETSC_FALSE; 573757de7509SStefano Zampini full_restr = PETSC_FALSE; 573857de7509SStefano Zampini } else { 573957de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 574057de7509SStefano Zampini restr = PETSC_TRUE; 574157de7509SStefano Zampini full_restr = PETSC_TRUE; 574257de7509SStefano Zampini } 574357de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 574457de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 574557de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 574657de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 574757de7509SStefano Zampini PetscInt psum; 574857de7509SStefano Zampini PetscMPIInt size; 574957de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 575057de7509SStefano Zampini else psum = 0; 575157de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 575257de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 575357de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 575457de7509SStefano Zampini } 575557de7509SStefano Zampini /* determine if we can go multilevel */ 575657de7509SStefano Zampini if (multilevel_requested) { 575757de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 575857de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 575957de7509SStefano Zampini } 576057de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 576157de7509SStefano Zampini 5762e4d548c7SStefano Zampini /* dump subassembling pattern */ 5763e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 5764e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 5765e4d548c7SStefano Zampini } 5766e4d548c7SStefano Zampini 57676e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 576827b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 57696e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 57706e683305SStefano Zampini const PetscInt *idxs; 57716e683305SStefano Zampini ISLocalToGlobalMapping tmap; 57726e683305SStefano Zampini 57736e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 57740be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 57756e683305SStefano Zampini /* allocate space for temporary storage */ 5776854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5777854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 57786e683305SStefano Zampini /* allocate for IS array */ 57796e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 57806e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 578127b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 578230368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5783854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 57846e683305SStefano Zampini /* dofs splitting */ 57856e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 57866e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 57876e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 57886e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 57896e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 57906e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 57916e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 579230368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 57936e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 57946e683305SStefano Zampini } 57956e683305SStefano Zampini /* neumann boundaries */ 57966e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 57976e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 57986e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 57996e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 58006e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 58016e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 58026e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 580330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 58046e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 58056e683305SStefano Zampini } 58066e683305SStefano Zampini /* free memory */ 58076e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 58086e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 58096e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 58106e683305SStefano Zampini } else { 58116e683305SStefano Zampini nis = 0; 58126e683305SStefano Zampini nisdofs = 0; 58136e683305SStefano Zampini nisneu = 0; 581430368db7SStefano Zampini nisvert = 0; 58156e683305SStefano Zampini isarray = NULL; 58166e683305SStefano Zampini } 58176e683305SStefano Zampini /* destroy no longer needed map */ 58186e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 58196e683305SStefano Zampini 582057de7509SStefano Zampini /* subassemble */ 582157de7509SStefano Zampini if (multilevel_allowed) { 582257de7509SStefano Zampini PetscBool reuse,reuser; 582357de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 582457de7509SStefano Zampini else reuse = PETSC_FALSE; 582557de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 582657de7509SStefano Zampini if (reuser) { 582757de7509SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray);CHKERRQ(ierr); 582874e2c79eSStefano Zampini } else { 582957de7509SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 583074e2c79eSStefano Zampini } 58311f4df5f7SStefano 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 */ 583274e2c79eSStefano Zampini } else { 583357de7509SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 58346e683305SStefano Zampini } 583557de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 583657de7509SStefano Zampini PetscMPIInt size; 583757de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 583857de7509SStefano Zampini if (!multilevel_allowed) { 583957de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 58406e683305SStefano Zampini } else { 584157de7509SStefano Zampini Mat A; 5842779c1cceSStefano Zampini 584357de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 584457de7509SStefano Zampini if (coarse_mat_is) { 584557de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 584657de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 584757de7509SStefano Zampini coarse_mat = coarse_mat_is; 584857de7509SStefano Zampini } 584957de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 585057de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 585157de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 5852779c1cceSStefano Zampini } 5853779c1cceSStefano Zampini } 585457de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 585557de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 58566e683305SStefano Zampini 58576e683305SStefano Zampini /* create local to global scatters for coarse problem */ 585868457ee5SStefano Zampini if (compute_vecs) { 58596e683305SStefano Zampini PetscInt lrows; 58606e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 586157de7509SStefano Zampini if (coarse_mat) { 586257de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 58636e683305SStefano Zampini } else { 58646e683305SStefano Zampini lrows = 0; 58656e683305SStefano Zampini } 58666e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 58676e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 58686e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 58696e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 58706e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 58716e683305SStefano Zampini } 58726e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 5873c8587f34SStefano Zampini 5874f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5875f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5876f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5877f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5878f9eb5b7dSStefano Zampini } else { 5879f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5880f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5881c8587f34SStefano Zampini } 5882c8587f34SStefano Zampini 58836e683305SStefano Zampini /* print some info if requested */ 58846e683305SStefano Zampini if (pcbddc->dbg_flag) { 58856e683305SStefano Zampini if (!multilevel_allowed) { 58866e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 58876e683305SStefano Zampini if (multilevel_requested) { 58886e683305SStefano 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); 58896e683305SStefano Zampini } else if (pcbddc->max_levels) { 58906e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 58916e683305SStefano Zampini } 58926e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 58936e683305SStefano Zampini } 58946e683305SStefano Zampini } 58956e683305SStefano Zampini 5896f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 589757de7509SStefano Zampini if (coarse_mat) { 58986a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 58996e683305SStefano Zampini if (pcbddc->dbg_flag) { 590057de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 59016e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 59026e683305SStefano Zampini } 5903f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5904312be037SStefano Zampini char prefix[256],str_level[16]; 5905e604994aSStefano Zampini size_t len; 590657de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5907422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5908c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5909f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 591057de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5911c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 59126e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5913c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5914c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5915e604994aSStefano Zampini /* prefix */ 5916e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5917e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5918e604994aSStefano Zampini if (!pcbddc->current_level) { 5919e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5920e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5921c8587f34SStefano Zampini } else { 5922e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5923312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5924312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 592534d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5926312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5927e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5928e604994aSStefano Zampini } 5929e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 59303e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 59313e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 59323e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 59333e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5934f9eb5b7dSStefano Zampini /* allow user customization */ 5935f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 59363e3c6dadSStefano Zampini } 59373e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 593851bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 59393e3c6dadSStefano Zampini if (nisdofs) { 59403e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 59413e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 59423e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 59433e3c6dadSStefano Zampini } 59443e3c6dadSStefano Zampini } 59453e3c6dadSStefano Zampini if (nisneu) { 59463e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 59473e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5948312be037SStefano Zampini } 594930368db7SStefano Zampini if (nisvert) { 595030368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 595130368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 595230368db7SStefano Zampini } 5953f9eb5b7dSStefano Zampini 5954f9eb5b7dSStefano Zampini /* get some info after set from options */ 5955f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5956f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 59574f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 59586e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5959f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5960f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5961f9eb5b7dSStefano Zampini } 596239f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 59634f3a063dSStefano Zampini if (isredundant) { 59644f3a063dSStefano Zampini KSP inner_ksp; 59654f3a063dSStefano Zampini PC inner_pc; 59664f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 59674f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 59684f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 59694f3a063dSStefano Zampini } 5970f9eb5b7dSStefano Zampini 597157de7509SStefano Zampini /* parameters which miss an API */ 597257de7509SStefano Zampini if (isbddc) { 5973720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 5974720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 597557de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 597627b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 597727b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 597827b6a85dSStefano Zampini pcbddc_coarse->benign_compute_nonetflux = PETSC_TRUE; 5979720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 598059e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 5981720d30f9SStefano Zampini } 5982d4d8cf7bSStefano Zampini } 59839881197aSStefano Zampini 59843301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 59855a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 59863301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 59873301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 59883301b35fSStefano Zampini } 59893301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 59903301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 59913301b35fSStefano Zampini } 59923301b35fSStefano Zampini if (pc->pmat->spd_set) { 59933301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 59943301b35fSStefano Zampini } 599527b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 599627b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 599727b6a85dSStefano Zampini } 59986e683305SStefano Zampini /* set operators */ 59995f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 60006e683305SStefano Zampini if (pcbddc->dbg_flag) { 60016e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 60026e683305SStefano Zampini } 60036e683305SStefano Zampini } 60046e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 6005b1ecc7b1SStefano Zampini #if 0 6006b9b85e73SStefano Zampini { 6007b9b85e73SStefano Zampini PetscViewer viewer; 6008b9b85e73SStefano Zampini char filename[256]; 6009b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 6010b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 60116a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6012b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 6013f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 6014b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 6015b9b85e73SStefano Zampini } 6016b9b85e73SStefano Zampini #endif 6017f9eb5b7dSStefano Zampini 601898a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 601998a51de6SStefano Zampini Vec crhs,csol; 602004708bb6SStefano Zampini 6021f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 6022f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 6023f347579bSStefano Zampini if (!csol) { 60242a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 6025f9eb5b7dSStefano Zampini } 6026f347579bSStefano Zampini if (!crhs) { 60272a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 6028f347579bSStefano Zampini } 6029b0f5fe93SStefano Zampini } 6030b0f5fe93SStefano Zampini 6031b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 6032b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 6033b0f5fe93SStefano Zampini 6034b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 60354f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 60364f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 60374f1b2e48SStefano Zampini } 6038b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 6039b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 6040b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6041b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6042b0f5fe93SStefano Zampini if (coarse_mat) { 6043b0f5fe93SStefano Zampini Vec nullv; 6044b0f5fe93SStefano Zampini PetscScalar *array,*array2; 6045b0f5fe93SStefano Zampini PetscInt nl; 6046b0f5fe93SStefano Zampini 6047b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 6048b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 6049b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6050b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 6051b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 6052b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 6053b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 6054b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 6055b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 6056b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 6057b0f5fe93SStefano Zampini } 6058b0f5fe93SStefano Zampini } 6059b0f5fe93SStefano Zampini 6060b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 6061b0f5fe93SStefano Zampini PetscBool ispreonly; 6062b0f5fe93SStefano Zampini 6063b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6064b0f5fe93SStefano Zampini PetscBool isnull; 6065b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 6066bef83e63SStefano Zampini if (isnull) { 6067b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 6068b0f5fe93SStefano Zampini } 6069bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 6070b0f5fe93SStefano Zampini } 6071b0f5fe93SStefano Zampini /* setup coarse ksp */ 6072b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 6073cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 6074cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 60756e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 6076c8587f34SStefano Zampini KSP check_ksp; 60772b510759SStefano Zampini KSPType check_ksp_type; 6078c8587f34SStefano Zampini PC check_pc; 60796e683305SStefano Zampini Vec check_vec,coarse_vec; 60806a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 60812b510759SStefano Zampini PetscInt its; 60826e683305SStefano Zampini PetscBool compute_eigs; 60836e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 60846e683305SStefano Zampini PetscInt neigs; 60858e185a42SStefano Zampini const char *prefix; 6086c8587f34SStefano Zampini 60872b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 60886e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 6089422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 609023ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6091f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 6092e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 6093e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 6094e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 60952b510759SStefano Zampini if (ispreonly) { 60962b510759SStefano Zampini check_ksp_type = KSPPREONLY; 60976e683305SStefano Zampini compute_eigs = PETSC_FALSE; 60982b510759SStefano Zampini } else { 6099cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 61006e683305SStefano Zampini compute_eigs = PETSC_TRUE; 6101c8587f34SStefano Zampini } 6102c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 61036e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 61046e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 61056e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 6106a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 6107a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 6108a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 6109a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 6110c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 6111c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 6112c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 6113c8587f34SStefano Zampini /* create random vec */ 61142701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 6115c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 61166e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 6117c8587f34SStefano Zampini /* solve coarse problem */ 61186e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 6119cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 61206e683305SStefano Zampini if (compute_eigs) { 6121854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 6122854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 61236e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 61246e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 61256e683305SStefano Zampini lambda_min = eigs_r[0]; 61266e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 61272701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 61282701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 6129cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 6130cbcc2c2aSStefano Zampini } 6131c8587f34SStefano Zampini } 6132c8587f34SStefano Zampini } 6133cbcc2c2aSStefano Zampini 6134c8587f34SStefano Zampini /* check coarse problem residual error */ 61356e683305SStefano Zampini if (pcbddc->dbg_flag) { 61366e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 61376e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 61386e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 6139c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 61406e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 61416e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 6142779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 61436e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 61446e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 61456e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 61466e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 6147b0f5fe93SStefano Zampini if (CoarseNullSpace) { 6148b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 6149b0f5fe93SStefano Zampini } 61506e683305SStefano Zampini if (compute_eigs) { 61516e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 6152deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 6153c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 61546e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 61556e683305SStefano 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); 61566e683305SStefano Zampini for (i=0;i<neigs;i++) { 61576e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 6158c8587f34SStefano Zampini } 61596e683305SStefano Zampini } 61606e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 61616e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 61626e683305SStefano Zampini } 6163e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 61642701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 6165c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 61666e683305SStefano Zampini if (compute_eigs) { 61676e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 61686e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 6169c8587f34SStefano Zampini } 61706e683305SStefano Zampini } 61716e683305SStefano Zampini } 6172bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 6173cbcc2c2aSStefano Zampini /* print additional info */ 6174cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 61756e683305SStefano Zampini /* waits until all processes reaches this point */ 61766e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 6177cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 6178cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6179cbcc2c2aSStefano Zampini } 6180cbcc2c2aSStefano Zampini 61812b510759SStefano Zampini /* free memory */ 6182fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 6183c8587f34SStefano Zampini PetscFunctionReturn(0); 6184c8587f34SStefano Zampini } 6185674ae819SStefano Zampini 6186f34684f1SStefano Zampini #undef __FUNCT__ 6187f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 6188f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 6189f34684f1SStefano Zampini { 6190f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6191f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 6192f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 6193dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 6194dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 619573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 6196dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 6197f34684f1SStefano Zampini PetscErrorCode ierr; 6198f34684f1SStefano Zampini 6199f34684f1SStefano Zampini PetscFunctionBegin; 6200f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 62016c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 6202dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 62033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 6204dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6205dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 6206dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 6207dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 6208dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 6209dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 62106c4ed002SBarry 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); 6211dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 6212dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6213dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 6214dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 6215dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 6216f34684f1SStefano Zampini 6217f34684f1SStefano Zampini /* check numbering */ 6218f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 6219019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 6220dc456d91SStefano Zampini PetscInt i; 6221b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 6222f34684f1SStefano Zampini 6223f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6224f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 6225f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 62261575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6227019a44ceSStefano Zampini /* counter */ 6228019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6229019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6230019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6231019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6232019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6233019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6234f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 6235f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 6236727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6237f34684f1SStefano Zampini } 6238f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6239f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6240f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6241e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6242e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6243e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6244e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6245f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6246019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6247f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6248019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 62492c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 625075c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 6251b9b85e73SStefano Zampini set_error = PETSC_TRUE; 62522c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 62532c66d082SStefano 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); 6254f34684f1SStefano Zampini } 6255f34684f1SStefano Zampini } 6256019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 6257b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 6258f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6259f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 6260f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 6261f34684f1SStefano Zampini } 6262f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6263f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6264e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6265e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6266f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 6267f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 6268b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 6269ca8b9ea9SStefano Zampini PetscInt *gidxs; 6270ca8b9ea9SStefano Zampini 6271ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 62723bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 6273f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 6274f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6275f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6276f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 62774bc2dc4bSStefano 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); 6278f34684f1SStefano Zampini } 6279f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6280ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 6281f34684f1SStefano Zampini } 6282f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 62831575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6284302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 6285f34684f1SStefano Zampini } 62868bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 6287f34684f1SStefano Zampini /* get back data */ 6288f34684f1SStefano Zampini *coarse_size_n = coarse_size; 6289f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 6290674ae819SStefano Zampini PetscFunctionReturn(0); 6291674ae819SStefano Zampini } 6292674ae819SStefano Zampini 6293e456f2a8SStefano Zampini #undef __FUNCT__ 6294e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 6295a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 6296e456f2a8SStefano Zampini { 6297e456f2a8SStefano Zampini IS localis_t; 6298a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 6299e456f2a8SStefano Zampini PetscScalar *vals; 6300e456f2a8SStefano Zampini PetscErrorCode ierr; 6301e456f2a8SStefano Zampini 6302e456f2a8SStefano Zampini PetscFunctionBegin; 6303a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 6304e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 6305854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 6306e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 6307e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6308a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 6309a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 63101035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 6311a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 63121035eff8SStefano Zampini } 6313a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 6314e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 6315e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 6316a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 6317a7dc3881SStefano Zampini /* now compute set in local ordering */ 6318a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6319a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6320a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6321a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 6322a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6323ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6324e456f2a8SStefano Zampini lsize++; 6325e456f2a8SStefano Zampini } 6326e456f2a8SStefano Zampini } 6327854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 6328a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 6329ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 6330e456f2a8SStefano Zampini idxs[lsize++] = i; 6331e456f2a8SStefano Zampini } 6332e456f2a8SStefano Zampini } 6333a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 6334a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 6335e456f2a8SStefano Zampini *localis = localis_t; 6336e456f2a8SStefano Zampini PetscFunctionReturn(0); 6337e456f2a8SStefano Zampini } 6338906d46d4SStefano Zampini 6339b96c3477SStefano Zampini #undef __FUNCT__ 6340b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 634108122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 6342b96c3477SStefano Zampini { 6343a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6344b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6345b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6346a64f4aa4SStefano Zampini Mat S_j; 6347b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6348b96c3477SStefano Zampini PetscBool free_used_adj; 6349b96c3477SStefano Zampini PetscErrorCode ierr; 6350b96c3477SStefano Zampini 6351b96c3477SStefano Zampini PetscFunctionBegin; 6352b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6353b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 635408122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6355b96c3477SStefano Zampini used_xadj = NULL; 6356b96c3477SStefano Zampini used_adjncy = NULL; 6357b96c3477SStefano Zampini } else { 635808122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 635908122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 636008122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 636108122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6362b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6363b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6364b96c3477SStefano Zampini } else { 63652fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6366b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6367b96c3477SStefano Zampini PetscInt nvtxs; 6368b96c3477SStefano Zampini 63692fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 63702fffb893SStefano Zampini if (flg_row) { 6371b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6372b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6373b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6374b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 63752fffb893SStefano Zampini } else { 63762fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 63772fffb893SStefano Zampini used_xadj = NULL; 63782fffb893SStefano Zampini used_adjncy = NULL; 63792fffb893SStefano Zampini } 63802fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6381b96c3477SStefano Zampini } 6382b96c3477SStefano Zampini } 6383d5574798SStefano Zampini 6384d5574798SStefano Zampini /* setup sub_schurs data */ 6385a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6386df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 6387df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 6388a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 638991af6908SStefano 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); 6390a64f4aa4SStefano Zampini } else { 63916816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 6392b7ab4a40SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE;; 6393a3df083aSStefano Zampini PetscInt benign_n; 639472b8c272SStefano Zampini Mat change = NULL; 63959d54b7f4SStefano Zampini Vec scaling = NULL; 639672b8c272SStefano Zampini IS change_primal = NULL; 6397a3df083aSStefano Zampini 63985feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 63995feab87aSStefano Zampini PetscInt n_vertices; 64005feab87aSStefano Zampini 64015feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 64022034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 64035feab87aSStefano Zampini } 640404708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 640504708bb6SStefano Zampini if (!isseqaij) { 640604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 640704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 640804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 640904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 641004708bb6SStefano Zampini } else { 6411511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 641204708bb6SStefano Zampini } 641304708bb6SStefano Zampini } 6414a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6415a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6416ca92afb2SStefano Zampini } else { 6417a3df083aSStefano Zampini benign_n = 0; 6418ca92afb2SStefano Zampini } 6419b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 6420b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 6421b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 642272b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 642322db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 6424b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 642522db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 6426b7ab4a40SStefano Zampini } 6427b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 6428b7ab4a40SStefano 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 */ 6429b7ab4a40SStefano Zampini if (need_change) { 643088c03ad3SStefano Zampini PC_IS *pcisf; 643188c03ad3SStefano Zampini PC_BDDC *pcbddcf; 643288c03ad3SStefano Zampini PC pcf; 643388c03ad3SStefano Zampini 6434e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 643588c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 643688c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 643788c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 643888c03ad3SStefano Zampini /* hacks */ 643988c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 644072b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 644172b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 644272b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 644372b8c272SStefano Zampini pcisf->n = pcis->n; 644472b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 644588c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 644688c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 644788c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 644888c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 644988c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 645088c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 645172b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 645288c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 645388c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 645472b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 645572b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 645672b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 645772b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 645872b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 645988c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 646072b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 646188c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 646288c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 646388c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 646488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 646588c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 646688c03ad3SStefano Zampini pcf->ops->destroy = NULL; 646788c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 646888c03ad3SStefano Zampini } 64699d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 647091af6908SStefano 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); 647172b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 647272b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 6473ca92afb2SStefano Zampini } 6474d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6475b96c3477SStefano Zampini 6476b96c3477SStefano Zampini /* free adjacency */ 6477b96c3477SStefano Zampini if (free_used_adj) { 6478b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6479b96c3477SStefano Zampini } 6480b96c3477SStefano Zampini PetscFunctionReturn(0); 6481b96c3477SStefano Zampini } 6482b96c3477SStefano Zampini 6483b96c3477SStefano Zampini #undef __FUNCT__ 6484b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 648508122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6486b96c3477SStefano Zampini { 6487b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6488b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6489b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6490b96c3477SStefano Zampini PCBDDCGraph graph; 6491b96c3477SStefano Zampini PetscErrorCode ierr; 6492b96c3477SStefano Zampini 6493b96c3477SStefano Zampini PetscFunctionBegin; 6494b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 649508122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 64963301b35fSStefano Zampini IS verticesIS,verticescomm; 64973301b35fSStefano Zampini PetscInt vsize,*idxs; 6498b96c3477SStefano Zampini 6499b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 65003301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 65013301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 65023301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 65033301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 65043301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6505b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 65067fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 6507441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 65083301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6509b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6510b96c3477SStefano Zampini } else { 6511b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6512b96c3477SStefano Zampini } 6513e4d548c7SStefano Zampini /* print some info */ 6514e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 6515e4d548c7SStefano Zampini IS vertices; 6516e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 6517e4d548c7SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6518e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 6519e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 6520e4d548c7SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 6521e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6522e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6523e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 6524e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 6525e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 6526e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6527e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6528e4d548c7SStefano Zampini } 6529b96c3477SStefano Zampini 6530b96c3477SStefano Zampini /* sub_schurs init */ 6531a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6532a64f4aa4SStefano Zampini 6533b96c3477SStefano Zampini /* free graph struct */ 653408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6535b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6536b96c3477SStefano Zampini } 6537b96c3477SStefano Zampini PetscFunctionReturn(0); 6538b96c3477SStefano Zampini } 6539fa34dd3eSStefano Zampini 6540fa34dd3eSStefano Zampini #undef __FUNCT__ 6541fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6542fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6543fa34dd3eSStefano Zampini { 6544fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6545fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6546fa34dd3eSStefano Zampini PetscErrorCode ierr; 6547fa34dd3eSStefano Zampini 6548fa34dd3eSStefano Zampini PetscFunctionBegin; 6549fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6550fa34dd3eSStefano Zampini IS zerodiag = NULL; 65514f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6552fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 65534f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 655475c01103SStefano Zampini PetscReal norm; 6555fa34dd3eSStefano Zampini PetscInt i; 6556fa34dd3eSStefano Zampini 6557fa34dd3eSStefano Zampini /* B0 and B0_B */ 6558fa34dd3eSStefano Zampini if (zerodiag) { 6559fa34dd3eSStefano Zampini IS dummy; 6560fa34dd3eSStefano Zampini 65614f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 65624f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6563fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6564fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6565fa34dd3eSStefano Zampini } 6566fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6567fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6568fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6569fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6570fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6571fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6572fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6573fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6574fa34dd3eSStefano Zampini /* S_j */ 6575fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6576fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6577fa34dd3eSStefano Zampini 6578fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6579fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6580fa34dd3eSStefano Zampini /* continuous in primal space */ 6581fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6582fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6583fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6584fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 65854f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 65864f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6587fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6588fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6589fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6590fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6591fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6592fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6593fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6594fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6595fa34dd3eSStefano Zampini 6596fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6597fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6598fa34dd3eSStefano Zampini /* local with Schur */ 6599fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6600fa34dd3eSStefano Zampini if (zerodiag) { 6601fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 66024f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6603fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6604fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6605fa34dd3eSStefano Zampini } 6606fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6607fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6608fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6609fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6610fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6611fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6612fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6613fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6614fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6615fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6616fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6617fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6618fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6619fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6620fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6621fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6622fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6623fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6624fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6625fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6626fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6627fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6628fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6629fa34dd3eSStefano Zampini if (zerodiag) { 6630fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6631fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 66324f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6633fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6634fa34dd3eSStefano Zampini } 6635fa34dd3eSStefano Zampini /* BDDC */ 6636fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6637fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6638fa34dd3eSStefano Zampini 6639fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6640fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6641fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6642fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 66434f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 66444f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6645fa34dd3eSStefano Zampini } 66464f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6647fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6648fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6649fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6650fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6651fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6652fa34dd3eSStefano Zampini } 6653fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6654fa34dd3eSStefano Zampini } 6655