1ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 3674ae819SStefano Zampini #include <petscblaslapack.h> 4674ae819SStefano Zampini 5906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y); 6906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y); 7906d46d4SStefano Zampini 8b1b3d7a2SStefano Zampini #if 0 9b1b3d7a2SStefano Zampini #undef __FUNCT__ 10b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 11b1b3d7a2SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc, MatNullSpace* adapt_nnsp) 12b1b3d7a2SStefano Zampini { 13b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 14b1b3d7a2SStefano Zampini PetscErrorCode ierr; 15b1b3d7a2SStefano Zampini 16b1b3d7a2SStefano Zampini PetscFunctionBegin; 17b1b3d7a2SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs[0],pcbddc->mat_graph,...);CHKERRQ(ierr); 18b1b3d7a2SStefano Zampini PetscFunctionReturn(0); 19b1b3d7a2SStefano Zampini } 20b1b3d7a2SStefano Zampini #endif 21b1b3d7a2SStefano Zampini 22674ae819SStefano Zampini #undef __FUNCT__ 23c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 24c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 25c8587f34SStefano Zampini { 26c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 278629588bSStefano Zampini PetscScalar *coarse_submat_vals; 28c8587f34SStefano Zampini PetscErrorCode ierr; 29c8587f34SStefano Zampini 30c8587f34SStefano Zampini PetscFunctionBegin; 31f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 325e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 33c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 34c8587f34SStefano Zampini 35684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 360fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 37684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 38c8587f34SStefano Zampini 39c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 40b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 41c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 42c8587f34SStefano Zampini } 43c8587f34SStefano Zampini 448629588bSStefano Zampini /* 458629588bSStefano Zampini Setup local correction and local part of coarse basis. 468629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 478629588bSStefano Zampini */ 4847f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 498629588bSStefano Zampini 508629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 518629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 528629588bSStefano Zampini 538629588bSStefano Zampini /* free */ 548629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 55c8587f34SStefano Zampini PetscFunctionReturn(0); 56c8587f34SStefano Zampini } 57c8587f34SStefano Zampini 58c8587f34SStefano Zampini #undef __FUNCT__ 59674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 60674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 61674ae819SStefano Zampini { 62674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 63674ae819SStefano Zampini PetscErrorCode ierr; 64674ae819SStefano Zampini 65674ae819SStefano Zampini PetscFunctionBegin; 66674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 67674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 68674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 69674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 70785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 71674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 72f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 73f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 74785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 7663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 77674ae819SStefano Zampini PetscFunctionReturn(0); 78674ae819SStefano Zampini } 79674ae819SStefano Zampini 80674ae819SStefano Zampini #undef __FUNCT__ 81674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 82674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 83674ae819SStefano Zampini { 84674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 85674ae819SStefano Zampini PetscErrorCode ierr; 86674ae819SStefano Zampini 87674ae819SStefano Zampini PetscFunctionBegin; 88b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 89674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 90674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 91674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 92b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 93674ae819SStefano Zampini PetscFunctionReturn(0); 94674ae819SStefano Zampini } 95674ae819SStefano Zampini 96674ae819SStefano Zampini #undef __FUNCT__ 97674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 98674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 99674ae819SStefano Zampini { 100674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 101674ae819SStefano Zampini PetscErrorCode ierr; 102674ae819SStefano Zampini 103674ae819SStefano Zampini PetscFunctionBegin; 104674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 105674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 106674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 107674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 10815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 10915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 110674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 111674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 112674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 113674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 114674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 115674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 1168ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 117674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 118674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 119674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 120f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 121f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 122f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 123f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 124727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 125f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 12670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 1276e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 128674ae819SStefano Zampini PetscFunctionReturn(0); 129674ae819SStefano Zampini } 130674ae819SStefano Zampini 131674ae819SStefano Zampini #undef __FUNCT__ 132f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 133f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 1346bfb1811SStefano Zampini { 1356bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1366bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1376bfb1811SStefano Zampini VecType impVecType; 138e9189074SStefano Zampini PetscInt n_constraints,n_R,old_size; 1396bfb1811SStefano Zampini PetscErrorCode ierr; 1406bfb1811SStefano Zampini 1416bfb1811SStefano Zampini PetscFunctionBegin; 142f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 143f4ddd8eeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 144f4ddd8eeSStefano Zampini } 145e7b262bdSStefano Zampini /* get sizes */ 146e9189074SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->n_actual_vertices; 147e9189074SStefano Zampini n_R = pcis->n-pcbddc->n_actual_vertices; 1486bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 149e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 150e7b262bdSStefano Zampini /* R nodes */ 151e7b262bdSStefano Zampini old_size = -1; 152e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 153e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 154e7b262bdSStefano Zampini } 155e7b262bdSStefano Zampini if (n_R != old_size) { 156e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 157e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 1586bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 1596bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 1606bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1616bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 162e7b262bdSStefano Zampini } 163e7b262bdSStefano Zampini /* local primal dofs */ 164e7b262bdSStefano Zampini old_size = -1; 165e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 166e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 167e7b262bdSStefano Zampini } 168e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 169e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 17083b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 171e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 1726bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 173e7b262bdSStefano Zampini } 174e7b262bdSStefano Zampini /* local explicit constraints */ 175e7b262bdSStefano Zampini old_size = -1; 176e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 177e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 178e7b262bdSStefano Zampini } 179e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 180e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 18183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 18283b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 18383b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 18483b7ccabSStefano Zampini } 1856bfb1811SStefano Zampini PetscFunctionReturn(0); 1866bfb1811SStefano Zampini } 1876bfb1811SStefano Zampini 1886bfb1811SStefano Zampini #undef __FUNCT__ 18947f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 19047f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 19188ebb749SStefano Zampini { 19225084f0cSStefano Zampini PetscErrorCode ierr; 19325084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 19488ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 19588ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 19625084f0cSStefano Zampini /* submatrices of local problem */ 19788ebb749SStefano Zampini Mat A_RV,A_VR,A_VV; 19825084f0cSStefano Zampini /* working matrices */ 19925084f0cSStefano Zampini Mat M1,M2,M3,C_CR; 20025084f0cSStefano Zampini /* working vectors */ 20125084f0cSStefano Zampini Vec vec1_C,vec2_C,vec1_V,vec2_V; 20225084f0cSStefano Zampini /* additional working stuff */ 20325084f0cSStefano Zampini IS is_aux; 20425084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 20525084f0cSStefano Zampini const PetscScalar *array,*row_cmat_values; 20625084f0cSStefano Zampini const PetscInt *row_cmat_indices,*idx_R_local; 207e9189074SStefano Zampini PetscInt *idx_V_B,*auxindices; 20825084f0cSStefano Zampini PetscInt n_vertices,n_constraints,size_of_constraint; 20925084f0cSStefano Zampini PetscInt i,j,n_R,n_D,n_B; 210b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 21145a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 21288ebb749SStefano Zampini MatType impMatType; 21325084f0cSStefano Zampini /* some shortcuts to scalars */ 21425084f0cSStefano Zampini PetscScalar zero=0.0,one=1.0,m_one=-1.0; 21525084f0cSStefano Zampini /* for debugging purposes */ 21688ebb749SStefano Zampini PetscReal *coarsefunctions_errors,*constraints_errors; 21788ebb749SStefano Zampini 21888ebb749SStefano Zampini PetscFunctionBegin; 219e9189074SStefano Zampini /* get number of vertices (corners plus constraints with change of basis) 220e9189074SStefano Zampini pcbddc->n_actual_vertices stores the actual number of vertices, pcbddc->n_vertices the number of corners computed */ 221e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 22288ebb749SStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 22388ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 22488ebb749SStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 22588ebb749SStefano Zampini n_R = pcis->n-n_vertices; 22688ebb749SStefano Zampini 22788ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 22888ebb749SStefano Zampini impMatType = MATSEQDENSE; 22988ebb749SStefano Zampini 23088ebb749SStefano Zampini /* Allocating some extra storage just to be safe */ 23188ebb749SStefano Zampini ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 23288ebb749SStefano Zampini for (i=0;i<pcis->n;i++) auxindices[i]=i; 23388ebb749SStefano Zampini 23488ebb749SStefano Zampini /* vertices in boundary numbering */ 235785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 2365e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->primal_indices_local_idxs,&i,idx_V_B);CHKERRQ(ierr); 23788ebb749SStefano Zampini if (i != n_vertices) { 23822d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 23988ebb749SStefano Zampini } 24088ebb749SStefano Zampini 24188ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 24288ebb749SStefano Zampini if (n_constraints) { 243f4ddd8eeSStefano Zampini /* see if we can save some allocations */ 244f4ddd8eeSStefano Zampini if (pcbddc->local_auxmat2) { 245f4ddd8eeSStefano Zampini PetscInt on_R,on_constraints; 246f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->local_auxmat2,&on_R,&on_constraints);CHKERRQ(ierr); 247f4ddd8eeSStefano Zampini if (on_R != n_R || on_constraints != n_constraints) { 248f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 249f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 250f4ddd8eeSStefano Zampini } 251f4ddd8eeSStefano Zampini } 25245a1bb75SStefano Zampini /* work vectors */ 25345a1bb75SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_C,&vec1_C);CHKERRQ(ierr); 25445a1bb75SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_C,&vec2_C);CHKERRQ(ierr); 25545a1bb75SStefano Zampini /* auxiliary matrices */ 256f4ddd8eeSStefano Zampini if (!pcbddc->local_auxmat2) { 25788ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 25825084f0cSStefano Zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 25988ebb749SStefano Zampini ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 26025084f0cSStefano Zampini ierr = MatSetUp(pcbddc->local_auxmat2);CHKERRQ(ierr); 261f4ddd8eeSStefano Zampini } 26288ebb749SStefano Zampini 26325084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 26425084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 2658ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 26625084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 26788ebb749SStefano Zampini 26888ebb749SStefano Zampini /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 26988ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 27088ebb749SStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 27188ebb749SStefano Zampini /* Get row of constraint matrix in R numbering */ 27225084f0cSStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 27325084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_R,size_of_constraint,row_cmat_indices,row_cmat_values,INSERT_VALUES);CHKERRQ(ierr); 27425084f0cSStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 27525084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_R);CHKERRQ(ierr); 27625084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_R);CHKERRQ(ierr); 27788ebb749SStefano Zampini /* Solve for row of constraint matrix in R numbering */ 27888ebb749SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 27925084f0cSStefano Zampini /* Set values in local_auxmat2 */ 28025084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec2_R,&array);CHKERRQ(ierr); 28188ebb749SStefano Zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 28225084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec2_R,&array);CHKERRQ(ierr); 28388ebb749SStefano Zampini } 28488ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28588ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28625084f0cSStefano Zampini ierr = MatScale(pcbddc->local_auxmat2,m_one);CHKERRQ(ierr); 28788ebb749SStefano Zampini 28888ebb749SStefano Zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 28925084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 29025084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 29188ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 29288ebb749SStefano Zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 29388ebb749SStefano Zampini ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 29425084f0cSStefano Zampini ierr = MatSetUp(M1);CHKERRQ(ierr); 29525084f0cSStefano Zampini ierr = MatDuplicate(M1,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 29625084f0cSStefano Zampini ierr = MatZeroEntries(M2);CHKERRQ(ierr); 29725084f0cSStefano Zampini ierr = VecSet(vec1_C,m_one);CHKERRQ(ierr); 29825084f0cSStefano Zampini ierr = MatDiagonalSet(M2,vec1_C,INSERT_VALUES);CHKERRQ(ierr); 29925084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 30025084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 30125084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 30288ebb749SStefano Zampini /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 303f4ddd8eeSStefano Zampini if (!pcbddc->local_auxmat1) { 30488ebb749SStefano Zampini ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 305f4ddd8eeSStefano Zampini } else { 306f4ddd8eeSStefano Zampini ierr = MatMatMult(M1,C_CR,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 307f4ddd8eeSStefano Zampini } 30888ebb749SStefano Zampini } 30988ebb749SStefano Zampini 31088ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 31188ebb749SStefano Zampini if (n_vertices) { 3123a50541eSStefano Zampini PetscInt ibs,mbs; 3133a50541eSStefano Zampini PetscBool issbaij; 314af732b37SStefano Zampini Mat newmat; 3153a50541eSStefano Zampini 3163a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 3179577ea80SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 3189577ea80SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 3193a50541eSStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ */ 3209577ea80SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 3219577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 3229577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3239577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 3249577ea80SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 3259577ea80SStefano Zampini } else { 3263a50541eSStefano Zampini /* this is safe */ 3279577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 3283a50541eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 3293a50541eSStefano Zampini if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 3303a50541eSStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 33145a1bb75SStefano Zampini /* which of the two approaches is faster? */ 3323a50541eSStefano Zampini /* ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 3333a50541eSStefano Zampini ierr = MatCreateTranspose(A_RV,&A_VR);CHKERRQ(ierr);*/ 3343a50541eSStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3353a50541eSStefano Zampini ierr = MatCreateTranspose(A_VR,&A_RV);CHKERRQ(ierr); 3363a50541eSStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 3373a50541eSStefano Zampini } else { 3389577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 3399577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3409577ea80SStefano Zampini } 3413a50541eSStefano Zampini } 3422a7a6963SBarry Smith ierr = MatCreateVecs(A_RV,&vec1_V,NULL);CHKERRQ(ierr); 34345a1bb75SStefano Zampini ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 34425084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 34588ebb749SStefano Zampini } 34688ebb749SStefano Zampini 34788ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 348f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 349f4ddd8eeSStefano Zampini PetscInt on_B,on_primal; 350f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 351f4ddd8eeSStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size) { 352f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 353f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 354f4ddd8eeSStefano Zampini } 355f4ddd8eeSStefano Zampini } 356f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_D) { 357f4ddd8eeSStefano Zampini PetscInt on_D,on_primal; 358f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,&on_primal);CHKERRQ(ierr); 359f4ddd8eeSStefano Zampini if (on_D != n_D || on_primal != pcbddc->local_primal_size) { 360f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 361f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 362f4ddd8eeSStefano Zampini } 363f4ddd8eeSStefano Zampini } 364f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 36588ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 36688ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 36788ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 36825084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_phi_B);CHKERRQ(ierr); 369f4ddd8eeSStefano Zampini } 370f4ddd8eeSStefano Zampini if ( (pcbddc->switch_static || pcbddc->dbg_flag) && !pcbddc->coarse_phi_D ) { 37188ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 37288ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 37388ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 37425084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_phi_D);CHKERRQ(ierr); 37588ebb749SStefano Zampini } 37688ebb749SStefano Zampini 37725084f0cSStefano Zampini if (pcbddc->dbg_flag) { 3788ce42a96SStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idx_R_local);CHKERRQ(ierr); 379785e854fSJed Brown ierr = PetscMalloc1(2*pcbddc->local_primal_size,&coarsefunctions_errors);CHKERRQ(ierr); 380785e854fSJed Brown ierr = PetscMalloc1(2*pcbddc->local_primal_size,&constraints_errors);CHKERRQ(ierr); 38188ebb749SStefano Zampini } 38288ebb749SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 383854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 38488ebb749SStefano Zampini 38588ebb749SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 38625084f0cSStefano Zampini 38725084f0cSStefano Zampini /* vertices */ 38888ebb749SStefano Zampini for (i=0;i<n_vertices;i++) { 38945a1bb75SStefano Zampini /* this should not be needed, but MatMult_BAIJ is broken when using compressed row routines */ 390f4ddd8eeSStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); /* TODO: REMOVE IT */ 39188ebb749SStefano Zampini ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 39288ebb749SStefano Zampini ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 39388ebb749SStefano Zampini ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 39488ebb749SStefano Zampini ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 39525084f0cSStefano Zampini /* simplified solution of saddle point problem with null rhs on constraints multipliers */ 39688ebb749SStefano Zampini ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 39788ebb749SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 39888ebb749SStefano Zampini ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 39988ebb749SStefano Zampini if (n_constraints) { 40088ebb749SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 40188ebb749SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 40288ebb749SStefano Zampini ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 40388ebb749SStefano Zampini } 40488ebb749SStefano Zampini ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 40588ebb749SStefano Zampini ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 40688ebb749SStefano Zampini 40788ebb749SStefano Zampini /* Set values in coarse basis function and subdomain part of coarse_mat */ 40888ebb749SStefano Zampini /* coarse basis functions */ 40988ebb749SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 41088ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 41188ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 41225084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 41388ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 41425084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 41588ebb749SStefano Zampini ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 4168eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 41788ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 41888ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 41925084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 42088ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 42125084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 42288ebb749SStefano Zampini } 42325084f0cSStefano Zampini /* subdomain contribution to coarse matrix. WARNING -> column major ordering */ 42425084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 42525084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[i*pcbddc->local_primal_size],array,n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 42625084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 42788ebb749SStefano Zampini if (n_constraints) { 42825084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 42925084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[i*pcbddc->local_primal_size+n_vertices],array,n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 43025084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 43188ebb749SStefano Zampini } 43288ebb749SStefano Zampini 43325084f0cSStefano Zampini /* check */ 43425084f0cSStefano Zampini if (pcbddc->dbg_flag) { 43525084f0cSStefano Zampini /* assemble subdomain vector on local nodes */ 43688ebb749SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 43725084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 4389f00e9b4SStefano Zampini if (n_R) { 43925084f0cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,n_R,idx_R_local,array,INSERT_VALUES);CHKERRQ(ierr); 4409f00e9b4SStefano Zampini } 44125084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 442e9189074SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],one,INSERT_VALUES);CHKERRQ(ierr); 44325084f0cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 44425084f0cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 44588ebb749SStefano Zampini /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 44688ebb749SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 44725084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 44825084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_vertices,auxindices,array,INSERT_VALUES);CHKERRQ(ierr); 44925084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 45088ebb749SStefano Zampini if (n_constraints) { 45125084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 45225084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_constraints,&auxindices[n_vertices],array,INSERT_VALUES);CHKERRQ(ierr); 45325084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 45488ebb749SStefano Zampini } 45525084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 45625084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 45788ebb749SStefano Zampini ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 45888ebb749SStefano Zampini /* check saddle point solution */ 45988ebb749SStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 46088ebb749SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 46188ebb749SStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 46288ebb749SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 46325084f0cSStefano Zampini /* shift by the identity matrix */ 46425084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,i,m_one,ADD_VALUES);CHKERRQ(ierr); 46525084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 46625084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 46788ebb749SStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 46888ebb749SStefano Zampini } 46988ebb749SStefano Zampini } 47088ebb749SStefano Zampini 47125084f0cSStefano Zampini /* constraints */ 47288ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 47388ebb749SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 47488ebb749SStefano Zampini ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 47588ebb749SStefano Zampini ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 47688ebb749SStefano Zampini ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 47725084f0cSStefano Zampini /* simplified solution of saddle point problem with null rhs on vertices multipliers */ 47888ebb749SStefano Zampini ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 47988ebb749SStefano Zampini ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 48088ebb749SStefano Zampini ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 48125084f0cSStefano Zampini if (n_vertices) { 48225084f0cSStefano Zampini ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 48325084f0cSStefano Zampini } 48488ebb749SStefano Zampini /* Set values in coarse basis function and subdomain part of coarse_mat */ 48588ebb749SStefano Zampini /* coarse basis functions */ 48625084f0cSStefano Zampini j = i+n_vertices; /* don't touch this! */ 48788ebb749SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 48888ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 48988ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49025084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 49125084f0cSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&j,array,INSERT_VALUES);CHKERRQ(ierr); 49225084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 4938eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 49488ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49588ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49625084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 49725084f0cSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&j,array,INSERT_VALUES);CHKERRQ(ierr); 49825084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 49988ebb749SStefano Zampini } 50025084f0cSStefano Zampini /* subdomain contribution to coarse matrix. WARNING -> column major ordering */ 50188ebb749SStefano Zampini if (n_vertices) { 50225084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 50325084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[j*pcbddc->local_primal_size],array,n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 50425084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 50588ebb749SStefano Zampini } 50625084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 50725084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[j*pcbddc->local_primal_size+n_vertices],array,n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 50825084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 50988ebb749SStefano Zampini 51025084f0cSStefano Zampini if (pcbddc->dbg_flag) { 51188ebb749SStefano Zampini /* assemble subdomain vector on nodes */ 51288ebb749SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 51325084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 5149f00e9b4SStefano Zampini if (n_R) { 51525084f0cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,n_R,idx_R_local,array,INSERT_VALUES);CHKERRQ(ierr); 5169f00e9b4SStefano Zampini } 51725084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 51825084f0cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 51925084f0cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 52088ebb749SStefano Zampini /* assemble subdomain vector of lagrange multipliers */ 52188ebb749SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 52288ebb749SStefano Zampini if (n_vertices) { 52325084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 52425084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_vertices,auxindices,array,INSERT_VALUES);CHKERRQ(ierr); 52525084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 52688ebb749SStefano Zampini } 52725084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 52825084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_constraints,&auxindices[n_vertices],array,INSERT_VALUES);CHKERRQ(ierr); 52925084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 53025084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 53125084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 53225084f0cSStefano Zampini ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 53388ebb749SStefano Zampini /* check saddle point solution */ 53488ebb749SStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 53588ebb749SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 53625084f0cSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[j]);CHKERRQ(ierr); 53788ebb749SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 53825084f0cSStefano Zampini /* shift by the identity matrix */ 53925084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,j,m_one,ADD_VALUES);CHKERRQ(ierr); 54025084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 54125084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 54225084f0cSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[j]);CHKERRQ(ierr); 54388ebb749SStefano Zampini } 54488ebb749SStefano Zampini } 54525084f0cSStefano Zampini /* call assembling routines for local coarse basis */ 54688ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 54788ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5488eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 54988ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55088ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55188ebb749SStefano Zampini } 55225084f0cSStefano Zampini 55388ebb749SStefano Zampini /* compute other basis functions for non-symmetric problems */ 554b9d89cd5SStefano Zampini if (!pcbddc->issym) { 555f4ddd8eeSStefano Zampini if (!pcbddc->coarse_psi_B) { 55688ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 55788ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 55888ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_B,impMatType);CHKERRQ(ierr); 55925084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_psi_B);CHKERRQ(ierr); 560f4ddd8eeSStefano Zampini } 561f4ddd8eeSStefano Zampini if ( (pcbddc->switch_static || pcbddc->dbg_flag) && !pcbddc->coarse_psi_D) { 56288ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 56388ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 56488ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_D,impMatType);CHKERRQ(ierr); 56525084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_psi_D);CHKERRQ(ierr); 56688ebb749SStefano Zampini } 56788ebb749SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 56888ebb749SStefano Zampini if (n_constraints) { 56988ebb749SStefano Zampini ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 57088ebb749SStefano Zampini for (j=0;j<n_constraints;j++) { 57125084f0cSStefano Zampini ierr = VecSetValue(vec1_C,j,coarse_submat_vals[(j+n_vertices)*pcbddc->local_primal_size+i],INSERT_VALUES);CHKERRQ(ierr); 57288ebb749SStefano Zampini } 57325084f0cSStefano Zampini ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 57425084f0cSStefano Zampini ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 57588ebb749SStefano Zampini } 57688ebb749SStefano Zampini if (i<n_vertices) { 57788ebb749SStefano Zampini ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 57888ebb749SStefano Zampini ierr = VecSetValue(vec1_V,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 57988ebb749SStefano Zampini ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 58088ebb749SStefano Zampini ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 58188ebb749SStefano Zampini ierr = MatMultTranspose(A_VR,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 58288ebb749SStefano Zampini if (n_constraints) { 58388ebb749SStefano Zampini ierr = MatMultTransposeAdd(C_CR,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 58488ebb749SStefano Zampini } 58588ebb749SStefano Zampini } else { 58688ebb749SStefano Zampini ierr = MatMultTranspose(C_CR,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 58788ebb749SStefano Zampini } 58888ebb749SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 58988ebb749SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 59088ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 59188ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 59225084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 59388ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 59425084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 59588ebb749SStefano Zampini if (i<n_vertices) { 59688ebb749SStefano Zampini ierr = MatSetValue(pcbddc->coarse_psi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 59788ebb749SStefano Zampini } 5988eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 59988ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60088ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60125084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 60288ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 60325084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 60488ebb749SStefano Zampini } 60588ebb749SStefano Zampini 60625084f0cSStefano Zampini if (pcbddc->dbg_flag) { 60788ebb749SStefano Zampini /* assemble subdomain vector on nodes */ 60888ebb749SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 60925084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 6109f00e9b4SStefano Zampini if (n_R) { 61125084f0cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,n_R,idx_R_local,array,INSERT_VALUES);CHKERRQ(ierr); 6129f00e9b4SStefano Zampini } 61325084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 61425084f0cSStefano Zampini if (i<n_vertices) { 615e9189074SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],one,INSERT_VALUES);CHKERRQ(ierr); 61688ebb749SStefano Zampini } 61725084f0cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 61825084f0cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 61925084f0cSStefano Zampini /* assemble subdomain vector of lagrange multipliers */ 62025084f0cSStefano Zampini for (j=0;j<pcbddc->local_primal_size;j++) { 62125084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,j,-coarse_submat_vals[j*pcbddc->local_primal_size+i],INSERT_VALUES);CHKERRQ(ierr); 62225084f0cSStefano Zampini } 62325084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 62425084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 62588ebb749SStefano Zampini /* check saddle point solution */ 62688ebb749SStefano Zampini ierr = MatMultTranspose(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 62788ebb749SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 62888ebb749SStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 62988ebb749SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 63025084f0cSStefano Zampini /* shift by the identity matrix */ 63125084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,i,m_one,ADD_VALUES);CHKERRQ(ierr); 63225084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 63325084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 63488ebb749SStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 63588ebb749SStefano Zampini } 63688ebb749SStefano Zampini } 63788ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 63888ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6398eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 64088ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 64188ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 64288ebb749SStefano Zampini } 643c0553b1fSStefano Zampini unsymmetric_check = PETSC_TRUE; 644c0553b1fSStefano Zampini } else { /* take references to already computed coarse basis */ 645c0553b1fSStefano Zampini unsymmetric_check = PETSC_FALSE; 646c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 647c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 648c0553b1fSStefano Zampini if (pcbddc->coarse_phi_D) { 649c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 650c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 651c0553b1fSStefano Zampini } 65288ebb749SStefano Zampini } 65388ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 65488ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 65588ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 65688ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 65725084f0cSStefano Zampini if (pcbddc->dbg_flag) { 65888ebb749SStefano Zampini Mat coarse_sub_mat; 65925084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 66088ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 66188ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 66288ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 66388ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 66488ebb749SStefano Zampini PetscReal real_value; 66588ebb749SStefano Zampini 66688ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 66788ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 66888ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 66988ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 67088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 67188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 672c0553b1fSStefano Zampini if (unsymmetric_check) { 67388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 67488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 67588ebb749SStefano Zampini } 67688ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 67788ebb749SStefano Zampini 67825084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 67925084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 68025084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 681c0553b1fSStefano Zampini if (unsymmetric_check) { 68288ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 68388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 68488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 68588ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 68688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 68788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 68888ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 68988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 69088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 69188ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 69288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 69388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 69488ebb749SStefano Zampini } else { 69588ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 69688ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 69788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 69888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 69988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 70088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 70188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 70288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 70388ebb749SStefano Zampini } 70488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 70588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 70688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 70788ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 70881d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 70988ebb749SStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&real_value);CHKERRQ(ierr); 7100fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 71125084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"----------------------------------\n");CHKERRQ(ierr); 71225084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 71325084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"matrix error = % 1.14e\n",real_value);CHKERRQ(ierr); 71425084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"coarse functions (phi) errors\n");CHKERRQ(ierr); 71588ebb749SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 71625084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); 71788ebb749SStefano Zampini } 71825084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"constraints (phi) errors\n");CHKERRQ(ierr); 71988ebb749SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 72025084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); 72188ebb749SStefano Zampini } 722c0553b1fSStefano Zampini if (unsymmetric_check) { 72325084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"coarse functions (psi) errors\n");CHKERRQ(ierr); 72488ebb749SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 72525084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,coarsefunctions_errors[i]);CHKERRQ(ierr); 72688ebb749SStefano Zampini } 72725084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"constraints (psi) errors\n");CHKERRQ(ierr); 72888ebb749SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 72925084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,constraints_errors[i]);CHKERRQ(ierr); 73088ebb749SStefano Zampini } 73188ebb749SStefano Zampini } 73225084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 73388ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 73488ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 73588ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 73688ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 73788ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 73888ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 73988ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 74088ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 74188ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 74288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 743c0553b1fSStefano Zampini if (unsymmetric_check) { 74488ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 74588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 74688ebb749SStefano Zampini } 74788ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 7488ce42a96SStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idx_R_local);CHKERRQ(ierr); 74988ebb749SStefano Zampini ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 75088ebb749SStefano Zampini ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 75188ebb749SStefano Zampini } 75288ebb749SStefano Zampini /* free memory */ 75388ebb749SStefano Zampini if (n_vertices) { 75488ebb749SStefano Zampini ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 75588ebb749SStefano Zampini ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 75688ebb749SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 75788ebb749SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 75888ebb749SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 75988ebb749SStefano Zampini } 76088ebb749SStefano Zampini if (n_constraints) { 76188ebb749SStefano Zampini ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 76288ebb749SStefano Zampini ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 76388ebb749SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 76488ebb749SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 76588ebb749SStefano Zampini } 76688ebb749SStefano Zampini ierr = PetscFree(auxindices);CHKERRQ(ierr); 7678629588bSStefano Zampini /* get back data */ 7688629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 76988ebb749SStefano Zampini PetscFunctionReturn(0); 77088ebb749SStefano Zampini } 77188ebb749SStefano Zampini 77288ebb749SStefano Zampini #undef __FUNCT__ 773d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 774b96c3477SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, MatStructure reuse, Mat* B) 775d65f70fdSStefano Zampini { 776d65f70fdSStefano Zampini Mat *work_mat; 777d65f70fdSStefano Zampini IS isrow_s,iscol_s; 778d65f70fdSStefano Zampini PetscBool rsorted,csorted; 779d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 780d65f70fdSStefano Zampini PetscErrorCode ierr; 781d65f70fdSStefano Zampini 782d65f70fdSStefano Zampini PetscFunctionBegin; 783d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 784d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 785d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 786d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 787d65f70fdSStefano Zampini 788d65f70fdSStefano Zampini if (!rsorted) { 789d65f70fdSStefano Zampini const PetscInt *idxs; 790d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 791d65f70fdSStefano Zampini 792d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 793d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 794d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 795d65f70fdSStefano Zampini idxs_perm_r[i] = i; 796d65f70fdSStefano Zampini } 797d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 798d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 799d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 800d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 801d65f70fdSStefano Zampini } 802d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 803d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 804d65f70fdSStefano Zampini } else { 805d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 806d65f70fdSStefano Zampini isrow_s = isrow; 807d65f70fdSStefano Zampini } 808d65f70fdSStefano Zampini 809d65f70fdSStefano Zampini if (!csorted) { 810d65f70fdSStefano Zampini if (isrow == iscol) { 811d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 812d65f70fdSStefano Zampini iscol_s = isrow_s; 813d65f70fdSStefano Zampini } else { 814d65f70fdSStefano Zampini const PetscInt *idxs; 815d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 816d65f70fdSStefano Zampini 817d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 818d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 819d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 820d65f70fdSStefano Zampini idxs_perm_c[i] = i; 821d65f70fdSStefano Zampini } 822d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 823d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 824d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 825d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 826d65f70fdSStefano Zampini } 827d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 828d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 829d65f70fdSStefano Zampini } 830d65f70fdSStefano Zampini } else { 831d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 832d65f70fdSStefano Zampini iscol_s = iscol; 833d65f70fdSStefano Zampini } 834d65f70fdSStefano Zampini 835b96c3477SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,reuse,&work_mat);CHKERRQ(ierr); 836d65f70fdSStefano Zampini 837d65f70fdSStefano Zampini if (!rsorted || !csorted) { 838d65f70fdSStefano Zampini Mat new_mat; 839d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 840d65f70fdSStefano Zampini 841d65f70fdSStefano Zampini if (!rsorted) { 842d65f70fdSStefano Zampini PetscInt *idxs_r,i; 843d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 844d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 845d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 846d65f70fdSStefano Zampini } 847d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 848d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 849d65f70fdSStefano Zampini } else { 850d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 851d65f70fdSStefano Zampini } 852d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 853d65f70fdSStefano Zampini 854d65f70fdSStefano Zampini if (!csorted) { 855d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 856d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 857d65f70fdSStefano Zampini is_perm_c = is_perm_r; 858d65f70fdSStefano Zampini } else { 859d65f70fdSStefano Zampini PetscInt *idxs_c,i; 860d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 861d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 862d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 863d65f70fdSStefano Zampini } 864d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 865d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 866d65f70fdSStefano Zampini } 867d65f70fdSStefano Zampini } else { 868d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 869d65f70fdSStefano Zampini } 870d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 871d65f70fdSStefano Zampini 872d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 873d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 874d65f70fdSStefano Zampini work_mat[0] = new_mat; 875d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 876d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 877d65f70fdSStefano Zampini } 878d65f70fdSStefano Zampini 879d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 880d65f70fdSStefano Zampini *B = work_mat[0]; 881d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 882d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 883d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 884d65f70fdSStefano Zampini PetscFunctionReturn(0); 885d65f70fdSStefano Zampini } 886d65f70fdSStefano Zampini 887d65f70fdSStefano Zampini #undef __FUNCT__ 8885e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 8895e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 890aa0d41d4SStefano Zampini { 891aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8925e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 893d65f70fdSStefano Zampini Mat new_mat; 8945e8657edSStefano Zampini IS is_local,is_global; 895d65f70fdSStefano Zampini PetscInt local_size; 896d65f70fdSStefano Zampini PetscBool isseqaij; 897aa0d41d4SStefano Zampini PetscErrorCode ierr; 898aa0d41d4SStefano Zampini 899aa0d41d4SStefano Zampini PetscFunctionBegin; 900aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 9015e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 9025e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 903906d46d4SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(matis->mapping,is_local,&is_global);CHKERRQ(ierr); 904906d46d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 905b96c3477SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,MAT_INITIAL_MATRIX,&new_mat);CHKERRQ(ierr); 906906d46d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 907906d46d4SStefano Zampini 908906d46d4SStefano Zampini /* check */ 909906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 910906d46d4SStefano Zampini Vec x,x_change; 911906d46d4SStefano Zampini PetscReal error; 912906d46d4SStefano Zampini 9135e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 914906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 9155e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 9165e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9175e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 918d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 9195e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9205e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 921906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 922906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 923906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 924906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 925906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 926906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 927906d46d4SStefano Zampini } 928906d46d4SStefano Zampini 92922d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 9309b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 93122d5777bSStefano Zampini if (isseqaij) { 932d65f70fdSStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 933aa0d41d4SStefano Zampini } else { 934aa0d41d4SStefano Zampini Mat work_mat; 935aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 936d65f70fdSStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 937aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 938aa0d41d4SStefano Zampini } 939d65f70fdSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 94045a1bb75SStefano Zampini /* 94145a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 942d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 94345a1bb75SStefano Zampini */ 944d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 945aa0d41d4SStefano Zampini PetscFunctionReturn(0); 946aa0d41d4SStefano Zampini } 947aa0d41d4SStefano Zampini 948aa0d41d4SStefano Zampini #undef __FUNCT__ 949a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 9508ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 951a64d13efSStefano Zampini { 952a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 953a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 9548ce42a96SStefano Zampini IS is_aux1,is_aux2; 955e9189074SStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 9563a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 9573a50541eSStefano Zampini PetscInt vbs,bs; 9584641a718SStefano Zampini PetscBT bitmask; 959a64d13efSStefano Zampini PetscErrorCode ierr; 960a64d13efSStefano Zampini 961a64d13efSStefano Zampini PetscFunctionBegin; 962b23d619eSStefano Zampini /* 963b23d619eSStefano Zampini No need to setup local scatters if 964b23d619eSStefano Zampini - primal space is unchanged 965b23d619eSStefano Zampini AND 966b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 967b23d619eSStefano Zampini AND 968b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 969b23d619eSStefano Zampini */ 970b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 971f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 972f4ddd8eeSStefano Zampini } 973f4ddd8eeSStefano Zampini /* destroy old objects */ 974f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 975f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 976f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 977a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 978a64d13efSStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 979e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 9804641a718SStefano Zampini /* create auxiliary bitmask */ 9814641a718SStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 9824641a718SStefano Zampini for (i=0;i<n_vertices;i++) { 983e9189074SStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->primal_indices_local_idxs[i]);CHKERRQ(ierr); 9844641a718SStefano Zampini } 9853a50541eSStefano Zampini 986a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 987854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 988a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 9894641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 990a64d13efSStefano Zampini idx_R_local[n_R] = i; 991a64d13efSStefano Zampini n_R++; 992a64d13efSStefano Zampini } 993a64d13efSStefano Zampini } 9943a50541eSStefano Zampini 9953a50541eSStefano Zampini /* Block code */ 9963a50541eSStefano Zampini vbs = 1; 9973a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 9983a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 9993a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 10003a50541eSStefano Zampini PetscInt *vary; 10013a50541eSStefano Zampini /* Verify if the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 1002785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 10033a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 1004e9189074SStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->primal_indices_local_idxs[i]/bs]++; 10053a50541eSStefano Zampini for (i=0; i<n_vertices; i++) { 10063a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 10073a50541eSStefano Zampini is_blocked = PETSC_FALSE; 10083a50541eSStefano Zampini break; 10093a50541eSStefano Zampini } 10103a50541eSStefano Zampini } 10113a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 10123a50541eSStefano Zampini vbs = bs; 10133a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 10143a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 10153a50541eSStefano Zampini } 10163a50541eSStefano Zampini } 10173a50541eSStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 10183a50541eSStefano Zampini } 10193a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 10203a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 1021a64d13efSStefano Zampini 1022a64d13efSStefano Zampini /* print some info if requested */ 1023a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 1024a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1025a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 10260fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1027a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 1028a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 10293a50541eSStefano 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->local_primal_size);CHKERRQ(ierr); 1030a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 1031a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1032a64d13efSStefano Zampini } 1033a64d13efSStefano Zampini 1034a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 10353a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1036854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 1037854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 1038a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 10394641a718SStefano Zampini for (i=0; i<n_D; i++) { 10404641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 10414641a718SStefano Zampini } 1042a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1043a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 10444641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 10454641a718SStefano Zampini aux_array1[j++] = i; 1046a64d13efSStefano Zampini } 1047a64d13efSStefano Zampini } 1048a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1049a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1050a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 10514641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 10524641a718SStefano Zampini aux_array2[j++] = i; 1053a64d13efSStefano Zampini } 1054a64d13efSStefano Zampini } 1055a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1056a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 1057a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 1058a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1059a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 1060a64d13efSStefano Zampini 10618eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1062785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 1063a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 10644641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 10654641a718SStefano Zampini aux_array1[j++] = i; 1066a64d13efSStefano Zampini } 1067a64d13efSStefano Zampini } 1068a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1069a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 1070a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1071a64d13efSStefano Zampini } 10724641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 10733a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1074a64d13efSStefano Zampini PetscFunctionReturn(0); 1075a64d13efSStefano Zampini } 1076a64d13efSStefano Zampini 1077304d26faSStefano Zampini 1078304d26faSStefano Zampini #undef __FUNCT__ 1079304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 1080684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 1081304d26faSStefano Zampini { 1082304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1083304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1084304d26faSStefano Zampini PC pc_temp; 1085304d26faSStefano Zampini Mat A_RR; 1086f4ddd8eeSStefano Zampini MatReuse reuse; 1087304d26faSStefano Zampini PetscScalar m_one = -1.0; 1088304d26faSStefano Zampini PetscReal value; 1089af732b37SStefano Zampini PetscInt n_D,n_R,ibs,mbs; 10909577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 1091304d26faSStefano Zampini PetscErrorCode ierr; 1092e604994aSStefano Zampini /* prefixes stuff */ 1093312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 1094e604994aSStefano Zampini size_t len; 1095304d26faSStefano Zampini 1096304d26faSStefano Zampini PetscFunctionBegin; 1097304d26faSStefano Zampini 1098e604994aSStefano Zampini /* compute prefixes */ 1099e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 1100e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 1101e604994aSStefano Zampini if (!pcbddc->current_level) { 1102e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1103e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1104e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1105e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1106e604994aSStefano Zampini } else { 1107e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 1108312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 1109e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 1110e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 1111312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 1112312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 111334d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 111434d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 1115e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1116e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1117e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 1118e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 1119e604994aSStefano Zampini } 1120e604994aSStefano Zampini 1121304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 1122684f6988SStefano Zampini if (dirichlet) { 1123ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 11248ce42a96SStefano Zampini ierr = ISGetSize(pcis->is_I_local,&n_D);CHKERRQ(ierr); 1125304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 1126304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 1127304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 1128304d26faSStefano Zampini /* default */ 1129304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1130e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 11319577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1132304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 11339577ea80SStefano Zampini if (issbaij) { 11349577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 11359577ea80SStefano Zampini } else { 1136304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 11379577ea80SStefano Zampini } 1138304d26faSStefano Zampini /* Allow user's customization */ 1139304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1140304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1141304d26faSStefano Zampini } 1142d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 1143304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1144304d26faSStefano Zampini if (!n_D) { 1145304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 1146304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1147304d26faSStefano Zampini } 1148304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 1149304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1150304d26faSStefano Zampini /* set ksp_D into pcis data */ 1151304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 1152304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 1153304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 1154684f6988SStefano Zampini } 1155304d26faSStefano Zampini 1156304d26faSStefano Zampini /* NEUMANN PROBLEM */ 1157684f6988SStefano Zampini A_RR = 0; 1158684f6988SStefano Zampini if (neumann) { 1159f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 11608ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 1161f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 1162f4ddd8eeSStefano Zampini PetscInt nn_R; 116381d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 1164f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1165f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 1166f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 1167f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 1168f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1169f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1170f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 1171727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 1172f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1173f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1174f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 1175f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 1176f4ddd8eeSStefano Zampini } 1177f4ddd8eeSStefano Zampini } 1178f4ddd8eeSStefano Zampini /* last check */ 1179d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 1180f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1181f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1182f4ddd8eeSStefano Zampini } 1183f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 1184f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1185f4ddd8eeSStefano Zampini } 1186f4ddd8eeSStefano Zampini /* extract A_RR */ 1187af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 1188af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 11893a50541eSStefano Zampini if (ibs != mbs) { 1190af732b37SStefano Zampini Mat newmat; 1191af732b37SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 1192f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1193af732b37SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 1194af732b37SStefano Zampini } else { 1195f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1196af732b37SStefano Zampini } 1197f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 1198304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 1199304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 1200304d26faSStefano Zampini /* default */ 1201304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1202e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 1203304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 12049577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 12059577ea80SStefano Zampini if (issbaij) { 12069577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 12079577ea80SStefano Zampini } else { 1208304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 12099577ea80SStefano Zampini } 1210304d26faSStefano Zampini /* Allow user's customization */ 1211304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1212304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1213304d26faSStefano Zampini } 1214d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 1215304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1216304d26faSStefano Zampini if (!n_R) { 1217304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 1218304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1219304d26faSStefano Zampini } 1220304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 1221304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1222684f6988SStefano Zampini } 1223304d26faSStefano Zampini 1224304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 12250fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 1226684f6988SStefano Zampini if (pcbddc->dbg_flag) { 1227684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1228684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1229684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1230684f6988SStefano Zampini } 1231684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 12320fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 12330fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 12340fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 12350fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 12360fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 1237304d26faSStefano Zampini /* need to be adapted? */ 1238b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1239b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1240b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 1241304d26faSStefano Zampini /* print info */ 1242304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1243e604994aSStefano 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); 1244304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1245304d26faSStefano Zampini } 1246b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 12478ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcis->is_I_local);CHKERRQ(ierr); 1248304d26faSStefano Zampini } 1249684f6988SStefano Zampini } 1250684f6988SStefano Zampini if (neumann) { /* Neumann */ 12510fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 12520fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 12530fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 12540fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 12550fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 1256304d26faSStefano Zampini /* need to be adapted? */ 1257b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1258b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1259304d26faSStefano Zampini /* print info */ 1260304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1261e604994aSStefano 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); 1262304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1263304d26faSStefano Zampini } 1264b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 12658ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcbddc->is_R_local);CHKERRQ(ierr); 1266304d26faSStefano Zampini } 12670fccc4e9SStefano Zampini } 1268684f6988SStefano Zampini } 1269304d26faSStefano Zampini /* free Neumann problem's matrix */ 1270304d26faSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1271304d26faSStefano Zampini PetscFunctionReturn(0); 1272304d26faSStefano Zampini } 1273304d26faSStefano Zampini 1274304d26faSStefano Zampini #undef __FUNCT__ 1275ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 127620c7b377SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec rhs, Vec sol, Vec work, PetscBool applytranspose) 1277674ae819SStefano Zampini { 1278674ae819SStefano Zampini PetscErrorCode ierr; 1279674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1280674ae819SStefano Zampini 1281674ae819SStefano Zampini PetscFunctionBegin; 128220c7b377SStefano Zampini if (applytranspose) { 1283674ae819SStefano Zampini if (pcbddc->local_auxmat1) { 128420c7b377SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,rhs,work);CHKERRQ(ierr); 128520c7b377SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,work,rhs,rhs);CHKERRQ(ierr); 128620c7b377SStefano Zampini } 128720c7b377SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 128820c7b377SStefano Zampini } else { 128920c7b377SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 129020c7b377SStefano Zampini if (pcbddc->local_auxmat1) { 129120c7b377SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,sol,work);CHKERRQ(ierr); 129220c7b377SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,work,sol,sol);CHKERRQ(ierr); 129320c7b377SStefano Zampini } 1294674ae819SStefano Zampini } 1295674ae819SStefano Zampini PetscFunctionReturn(0); 1296674ae819SStefano Zampini } 1297674ae819SStefano Zampini 1298dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 1299674ae819SStefano Zampini #undef __FUNCT__ 1300674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 1301dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 1302674ae819SStefano Zampini { 1303674ae819SStefano Zampini PetscErrorCode ierr; 1304674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1305674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 1306674ae819SStefano Zampini const PetscScalar zero = 0.0; 1307674ae819SStefano Zampini 1308674ae819SStefano Zampini PetscFunctionBegin; 1309dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 1310dc359a40SStefano Zampini if (applytranspose) { 1311674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 13128eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 1313dc359a40SStefano Zampini } else { 1314674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 1315674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 131615aaf578SStefano Zampini } 131712edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 131812edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 131912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 132012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 132112edc857SStefano Zampini 13229f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 132312edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 132412edc857SStefano Zampini if (pcbddc->coarse_ksp) { 132512edc857SStefano Zampini if (applytranspose) { 132612edc857SStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 132712edc857SStefano Zampini } else { 132812edc857SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 132912edc857SStefano Zampini } 133012edc857SStefano Zampini } 1331674ae819SStefano Zampini 1332674ae819SStefano Zampini /* Local solution on R nodes */ 13339f00e9b4SStefano Zampini if (pcis->n) { 1334674ae819SStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 1335674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1336674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13378eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1338674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1339674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1340674ae819SStefano Zampini } 134120c7b377SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcbddc->vec1_R,pcbddc->vec2_R,pcbddc->vec1_C,applytranspose);CHKERRQ(ierr); 1342674ae819SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1343674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1344674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13458eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1346674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1347674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1348674ae819SStefano Zampini } 13499f00e9b4SStefano Zampini } 1350674ae819SStefano Zampini 13519f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 13529f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 135312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1354674ae819SStefano Zampini 1355674ae819SStefano Zampini /* Sum contributions from two levels */ 1356dc359a40SStefano Zampini if (applytranspose) { 1357dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 1358dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1359dc359a40SStefano Zampini } else { 1360674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 13618eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1362dc359a40SStefano Zampini } 1363674ae819SStefano Zampini PetscFunctionReturn(0); 1364674ae819SStefano Zampini } 1365674ae819SStefano Zampini 136612edc857SStefano Zampini /* TODO: the following two function can be optimized using VecPlaceArray whenever possible and using overlap flag */ 1367674ae819SStefano Zampini #undef __FUNCT__ 1368674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 136912edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 1370674ae819SStefano Zampini { 1371674ae819SStefano Zampini PetscErrorCode ierr; 1372674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 137312edc857SStefano Zampini PetscScalar *array,*array2; 137412edc857SStefano Zampini Vec from,to; 1375674ae819SStefano Zampini 1376674ae819SStefano Zampini PetscFunctionBegin; 137712edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 137812edc857SStefano Zampini from = pcbddc->coarse_vec; 137912edc857SStefano Zampini to = pcbddc->vec1_P; 138012edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 138112edc857SStefano Zampini Vec tvec; 138212edc857SStefano Zampini PetscInt lsize; 138312edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 138412edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 138512edc857SStefano Zampini ierr = VecGetArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 138612edc857SStefano Zampini ierr = VecGetArray(from,&array2);CHKERRQ(ierr); 138712edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 138812edc857SStefano Zampini ierr = VecRestoreArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 138912edc857SStefano Zampini ierr = VecRestoreArray(from,&array2);CHKERRQ(ierr); 139012edc857SStefano Zampini } 139112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 139212edc857SStefano Zampini from = pcbddc->vec1_P; 139312edc857SStefano Zampini to = pcbddc->coarse_vec; 139412edc857SStefano Zampini } 139512edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 1396674ae819SStefano Zampini PetscFunctionReturn(0); 1397674ae819SStefano Zampini } 1398674ae819SStefano Zampini 1399674ae819SStefano Zampini #undef __FUNCT__ 1400674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 140112edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 1402674ae819SStefano Zampini { 1403674ae819SStefano Zampini PetscErrorCode ierr; 1404674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 140512edc857SStefano Zampini PetscScalar *array,*array2; 140612edc857SStefano Zampini Vec from,to; 1407674ae819SStefano Zampini 1408674ae819SStefano Zampini PetscFunctionBegin; 140912edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 141012edc857SStefano Zampini from = pcbddc->coarse_vec; 141112edc857SStefano Zampini to = pcbddc->vec1_P; 141212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 141312edc857SStefano Zampini from = pcbddc->vec1_P; 141412edc857SStefano Zampini to = pcbddc->coarse_vec; 141512edc857SStefano Zampini } 141612edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 141712edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 141812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 141912edc857SStefano Zampini Vec tvec; 142012edc857SStefano Zampini PetscInt lsize; 142112edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 142212edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 142312edc857SStefano Zampini ierr = VecGetArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 142412edc857SStefano Zampini ierr = VecGetArray(tvec,&array2);CHKERRQ(ierr); 142512edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 142612edc857SStefano Zampini ierr = VecRestoreArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 142712edc857SStefano Zampini ierr = VecRestoreArray(tvec,&array2);CHKERRQ(ierr); 142812edc857SStefano Zampini } 142912edc857SStefano Zampini } 1430674ae819SStefano Zampini PetscFunctionReturn(0); 1431674ae819SStefano Zampini } 1432674ae819SStefano Zampini 1433984c4197SStefano Zampini /* uncomment for testing purposes */ 1434984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 1435674ae819SStefano Zampini #undef __FUNCT__ 1436674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 1437674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 1438674ae819SStefano Zampini { 1439674ae819SStefano Zampini PetscErrorCode ierr; 1440674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1441674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1442674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1443984c4197SStefano Zampini /* constraint and (optionally) change of basis matrix implemented as SeqAIJ */ 1444674ae819SStefano Zampini MatType impMatType=MATSEQAIJ; 1445984c4197SStefano Zampini /* one and zero */ 1446984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 1447984c4197SStefano Zampini /* space to store constraints and their local indices */ 1448984c4197SStefano Zampini PetscScalar *temp_quadrature_constraint; 1449984c4197SStefano Zampini PetscInt *temp_indices,*temp_indices_to_constraint,*temp_indices_to_constraint_B; 1450984c4197SStefano Zampini /* iterators */ 1451984c4197SStefano Zampini PetscInt i,j,k,total_counts,temp_start_ptr; 1452984c4197SStefano Zampini /* stuff to store connected components stored in pcbddc->mat_graph */ 1453984c4197SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges,*used_IS; 1454984c4197SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges; 1455984c4197SStefano Zampini /* near null space stuff */ 1456674ae819SStefano Zampini MatNullSpace nearnullsp; 1457674ae819SStefano Zampini const Vec *nearnullvecs; 1458674ae819SStefano Zampini Vec *localnearnullsp; 1459984c4197SStefano Zampini PetscBool nnsp_has_cnst; 1460984c4197SStefano Zampini PetscInt nnsp_size; 1461984c4197SStefano Zampini PetscScalar *array; 1462984c4197SStefano Zampini /* BLAS integers */ 1463e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 1464e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 1465c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 1466984c4197SStefano Zampini /* LAPACK working arrays for SVD or POD */ 1467242a89d7SStefano Zampini PetscBool skip_lapack; 1468984c4197SStefano Zampini PetscScalar *work; 1469984c4197SStefano Zampini PetscReal *singular_vals; 1470984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1471984c4197SStefano Zampini PetscReal *rwork; 1472674ae819SStefano Zampini #endif 1473984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1474e310c8b4SStefano Zampini PetscBLASInt Blas_one_2=1; 1475984c4197SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 1476b7d8b9f8SStefano Zampini #else 1477b7d8b9f8SStefano Zampini PetscBLASInt dummy_int_1=1,dummy_int_2=1; 1478b7d8b9f8SStefano Zampini PetscScalar dummy_scalar_1=0.0,dummy_scalar_2=0.0; 1479984c4197SStefano Zampini #endif 1480727cdba6SStefano Zampini /* reuse */ 1481727cdba6SStefano Zampini PetscInt olocal_primal_size; 1482727cdba6SStefano Zampini PetscInt *oprimal_indices_local_idxs; 1483984c4197SStefano Zampini /* change of basis */ 1484984c4197SStefano Zampini PetscInt *aux_primal_numbering,*aux_primal_minloc,*global_indices; 1485a717540cSStefano Zampini PetscBool boolforchange,qr_needed; 1486a717540cSStefano Zampini PetscBT touched,change_basis,qr_needed_idx; 1487984c4197SStefano Zampini /* auxiliary stuff */ 148839e2fb2aSStefano Zampini PetscInt *nnz,*is_indices,*aux_primal_numbering_B; 1489911cabfeSStefano Zampini PetscInt ncc,*gidxs,*permutation,*temp_indices_to_constraint_work; 1490911cabfeSStefano Zampini PetscScalar *temp_quadrature_constraint_work; 1491984c4197SStefano Zampini /* some quantities */ 149245a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 1493984c4197SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint,max_constraints,temp_constraints; 1494984c4197SStefano Zampini 1495674ae819SStefano Zampini 1496674ae819SStefano Zampini PetscFunctionBegin; 14978e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 14988e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 14998e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1500674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 1501d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 1502d06fc5fdSStefano Zampini /* free unneeded index sets */ 1503d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 1504d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 1505674ae819SStefano Zampini } 1506d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 1507d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 1508d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 1509d06fc5fdSStefano Zampini } 1510d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 1511d06fc5fdSStefano Zampini n_ISForEdges = 0; 1512d06fc5fdSStefano Zampini } 1513d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 1514d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 1515d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 1516d06fc5fdSStefano Zampini } 1517d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 1518d06fc5fdSStefano Zampini n_ISForFaces = 0; 1519d06fc5fdSStefano Zampini } 1520d06fc5fdSStefano Zampini /* HACKS (the following two blocks of code) */ 1521b9b85e73SStefano Zampini if (!ISForVertices && pcbddc->NullSpace && !pcbddc->user_ChangeOfBasisMatrix) { 1522b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1523d06fc5fdSStefano Zampini if (!ISForEdges) { 1524d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 1525d06fc5fdSStefano Zampini } 1526b8ffe317SStefano Zampini } 152798a51de6SStefano Zampini if (pcbddc->NullSpace) { 152898a51de6SStefano Zampini /* use_change_of_basis should be consistent among processors */ 1529d06fc5fdSStefano Zampini PetscBool tbool[2],gbool[2]; 1530d06fc5fdSStefano Zampini tbool [0] = pcbddc->use_change_of_basis; 1531d06fc5fdSStefano Zampini tbool [1] = pcbddc->use_change_on_faces; 1532d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1533d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 1534d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 153598a51de6SStefano Zampini } 1536984c4197SStefano Zampini /* print some info */ 1537674ae819SStefano Zampini if (pcbddc->dbg_flag) { 15380fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1539674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 1540674ae819SStefano Zampini i = 0; 1541674ae819SStefano Zampini if (ISForVertices) { 1542674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&i);CHKERRQ(ierr); 1543674ae819SStefano Zampini } 1544674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices\n",PetscGlobalRank,i);CHKERRQ(ierr); 1545674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges\n",PetscGlobalRank,n_ISForEdges);CHKERRQ(ierr); 154615aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces\n",PetscGlobalRank,n_ISForFaces);CHKERRQ(ierr); 1547674ae819SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1548674ae819SStefano Zampini } 1549674ae819SStefano Zampini /* check if near null space is attached to global mat */ 1550674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 1551674ae819SStefano Zampini if (nearnullsp) { 1552674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1553f4ddd8eeSStefano Zampini /* remove any stored info */ 1554f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1555f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1556f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 1557f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 1558f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 1559473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1560f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1561f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 1562f4ddd8eeSStefano Zampini } 1563984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 1564984c4197SStefano Zampini nnsp_size = 0; 1565674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 1566674ae819SStefano Zampini } 1567984c4197SStefano Zampini /* get max number of constraints on a single cc */ 1568984c4197SStefano Zampini max_constraints = nnsp_size; 1569984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 1570984c4197SStefano Zampini 1571674ae819SStefano Zampini /* 1572674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 1573674ae819SStefano Zampini - temp_indices will contain start index of each constraint stored as follows 1574911cabfeSStefano Zampini - temp_indices_to_constraint [temp_indices[i],...,temp_indices[i+1]-1] will contain the indices (in local numbering) on which the constraint acts 1575911cabfeSStefano Zampini - temp_indices_to_constraint_B[temp_indices[i],...,temp_indices[i+1]-1] will contain the indices (in boundary numbering) on which the constraint acts 1576911cabfeSStefano Zampini - temp_quadrature_constraint [temp_indices[i],...,temp_indices[i+1]-1] will contain the scalars representing the constraint itself 1577674ae819SStefano Zampini */ 1578674ae819SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 1579984c4197SStefano Zampini total_counts *= max_constraints; 1580674ae819SStefano Zampini n_vertices = 0; 1581674ae819SStefano Zampini if (ISForVertices) { 1582674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 1583674ae819SStefano Zampini } 1584674ae819SStefano Zampini total_counts += n_vertices; 1585854ce69bSBarry Smith ierr = PetscMalloc1(total_counts+1,&temp_indices);CHKERRQ(ierr); 15864641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 1587674ae819SStefano Zampini total_counts = 0; 1588674ae819SStefano Zampini max_size_of_constraint = 0; 1589674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 1590674ae819SStefano Zampini if (i<n_ISForEdges) { 1591674ae819SStefano Zampini used_IS = &ISForEdges[i]; 1592674ae819SStefano Zampini } else { 1593674ae819SStefano Zampini used_IS = &ISForFaces[i-n_ISForEdges]; 1594674ae819SStefano Zampini } 1595674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 1596674ae819SStefano Zampini total_counts += j; 1597674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 1598674ae819SStefano Zampini } 1599984c4197SStefano Zampini total_counts *= max_constraints; 1600674ae819SStefano Zampini total_counts += n_vertices; 1601906d46d4SStefano Zampini ierr = PetscMalloc3(total_counts,&temp_quadrature_constraint,total_counts,&temp_indices_to_constraint,total_counts,&temp_indices_to_constraint_B);CHKERRQ(ierr); 1602984c4197SStefano Zampini /* get local part of global near null space vectors */ 1603785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 1604984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 1605984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 1606984c4197SStefano Zampini ierr = VecScatterBegin(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1607984c4197SStefano Zampini ierr = VecScatterEnd(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1608984c4197SStefano Zampini } 1609674ae819SStefano Zampini 1610242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 1611242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 1612a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 1613242a89d7SStefano Zampini 16148f1c130eSStefano Zampini /* allocate some auxiliary stuff */ 16158f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 16168f1c130eSStefano Zampini ierr = PetscMalloc4(max_size_of_constraint,&gidxs,max_size_of_constraint,&permutation,max_size_of_constraint,&temp_indices_to_constraint_work,max_size_of_constraint,&temp_quadrature_constraint_work);CHKERRQ(ierr); 16178f1c130eSStefano Zampini } 16188f1c130eSStefano Zampini 1619984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 1620a773dcb8SStefano Zampini if (!skip_lapack) { 1621674ae819SStefano Zampini PetscScalar temp_work; 1622911cabfeSStefano Zampini 1623674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1624984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 1625785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 1626785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 1627785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 1628674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1629785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 1630674ae819SStefano Zampini #endif 1631674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1632c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 1633c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 1634674ae819SStefano Zampini lwork = -1; 1635674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1636674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1637c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 1638674ae819SStefano Zampini #else 1639c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 1640674ae819SStefano Zampini #endif 1641674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1642984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 1643674ae819SStefano Zampini #else /* on missing GESVD */ 1644674ae819SStefano Zampini /* SVD */ 1645674ae819SStefano Zampini PetscInt max_n,min_n; 1646674ae819SStefano Zampini max_n = max_size_of_constraint; 1647984c4197SStefano Zampini min_n = max_constraints; 1648984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 1649674ae819SStefano Zampini min_n = max_size_of_constraint; 1650984c4197SStefano Zampini max_n = max_constraints; 1651674ae819SStefano Zampini } 1652785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 1653674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1654785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 1655674ae819SStefano Zampini #endif 1656674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1657674ae819SStefano Zampini lwork = -1; 1658e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 1659e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 1660b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 1661674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1662674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1663e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[0],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,&temp_work,&lwork,&lierr)); 1664674ae819SStefano Zampini #else 1665e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[0],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,&temp_work,&lwork,rwork,&lierr)); 1666674ae819SStefano Zampini #endif 1667674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1668984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 1669984c4197SStefano Zampini #endif /* on missing GESVD */ 1670674ae819SStefano Zampini /* Allocate optimal workspace */ 1671674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 1672854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 1673674ae819SStefano Zampini } 1674674ae819SStefano Zampini /* Now we can loop on constraining sets */ 1675674ae819SStefano Zampini total_counts = 0; 1676674ae819SStefano Zampini temp_indices[0] = 0; 1677674ae819SStefano Zampini /* vertices */ 1678674ae819SStefano Zampini if (ISForVertices) { 1679674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1680674ae819SStefano Zampini if (nnsp_has_cnst) { /* consider all vertices */ 168139e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 1682674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1683674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1684674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1685674ae819SStefano Zampini total_counts++; 1686674ae819SStefano Zampini } 1687674ae819SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 1688984c4197SStefano Zampini PetscBool used_vertex; 1689674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1690674ae819SStefano Zampini used_vertex = PETSC_FALSE; 1691674ae819SStefano Zampini k = 0; 1692674ae819SStefano Zampini while (!used_vertex && k<nnsp_size) { 1693984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1694984c4197SStefano Zampini if (PetscAbsScalar(array[is_indices[i]])>0.0) { 1695674ae819SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1696674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1697674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1698674ae819SStefano Zampini total_counts++; 1699674ae819SStefano Zampini used_vertex = PETSC_TRUE; 1700674ae819SStefano Zampini } 1701984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1702674ae819SStefano Zampini k++; 1703674ae819SStefano Zampini } 1704674ae819SStefano Zampini } 1705674ae819SStefano Zampini } 1706674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1707674ae819SStefano Zampini n_vertices = total_counts; 1708674ae819SStefano Zampini } 1709984c4197SStefano Zampini 1710674ae819SStefano Zampini /* edges and faces */ 1711911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 1712911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 1713911cabfeSStefano Zampini used_IS = &ISForEdges[ncc]; 1714984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 1715674ae819SStefano Zampini } else { 1716911cabfeSStefano Zampini used_IS = &ISForFaces[ncc-n_ISForEdges]; 1717984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 1718674ae819SStefano Zampini } 1719674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 1720674ae819SStefano Zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 1721674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 1722674ae819SStefano Zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1723984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 1724984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 1725674ae819SStefano Zampini if (nnsp_has_cnst) { 17265b08dc53SStefano Zampini PetscScalar quad_value; 1727674ae819SStefano Zampini temp_constraints++; 1728a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 1729674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 1730a773dcb8SStefano Zampini } else { 1731a773dcb8SStefano Zampini quad_value = 1.0; 1732a773dcb8SStefano Zampini } 173339e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1734674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1735674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 1736674ae819SStefano Zampini } 1737911cabfeSStefano Zampini /* sort by global ordering if using lapack subroutines */ 17388f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1739911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 1740911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1741911cabfeSStefano Zampini permutation[j]=j; 1742911cabfeSStefano Zampini } 1743911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 1744911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1745911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 1746911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 1747911cabfeSStefano Zampini } 1748911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1749911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 1750911cabfeSStefano Zampini } 1751674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 1752674ae819SStefano Zampini total_counts++; 1753674ae819SStefano Zampini } 1754674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 1755984c4197SStefano Zampini PetscReal real_value; 1756984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 175739e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1758674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1759984c4197SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array[is_indices[j]]; 1760674ae819SStefano Zampini } 1761984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1762984c4197SStefano Zampini /* check if array is null on the connected component */ 1763e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 1764e310c8b4SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,&temp_quadrature_constraint[temp_indices[total_counts]],&Blas_one)); 17655b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 1766911cabfeSStefano Zampini /* sort by global ordering if using lapack subroutines */ 17678f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1768911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 1769911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1770911cabfeSStefano Zampini permutation[j]=j; 1771911cabfeSStefano Zampini } 1772911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 1773911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1774911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 1775911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 1776911cabfeSStefano Zampini } 1777911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1778911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 1779911cabfeSStefano Zampini } 1780674ae819SStefano Zampini temp_constraints++; 1781674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 1782674ae819SStefano Zampini total_counts++; 1783674ae819SStefano Zampini } 1784674ae819SStefano Zampini } 1785674ae819SStefano Zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 178645a1bb75SStefano Zampini valid_constraints = temp_constraints; 1787eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 1788a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 1789a773dcb8SStefano Zampini PetscScalar norm; 1790a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 1791a773dcb8SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one)); 1792a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 1793a773dcb8SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one)); 1794a773dcb8SStefano Zampini } else { /* perform SVD */ 1795984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 1796674ae819SStefano Zampini 1797674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1798984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 1799984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 1800984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 1801984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 1802984c4197SStefano Zampini from that computed using LAPACKgesvd 1803984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 1804984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 1805984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 1806674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 1807e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 1808984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1809674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 1810674ae819SStefano Zampini for (k=0;k<j+1;k++) { 1811e310c8b4SStefano Zampini PetscStackCallBLAS("BLASdot",correlation_mat[j*temp_constraints+k]=BLASdot_(&Blas_N,&temp_quadrature_constraint[temp_indices[temp_start_ptr+k]],&Blas_one,&temp_quadrature_constraint[temp_indices[temp_start_ptr+j]],&Blas_one_2)); 1812674ae819SStefano Zampini } 1813674ae819SStefano Zampini } 1814e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 1815e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 1816e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 1817674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1818c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 1819674ae819SStefano Zampini #else 1820c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 1821674ae819SStefano Zampini #endif 1822674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1823984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 1824984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 1825674ae819SStefano Zampini j = 0; 1826984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 1827674ae819SStefano Zampini total_counts = total_counts-j; 182845a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 1829e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 1830c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 1831c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 1832c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 1833c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 1834c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 1835c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 1836674ae819SStefano Zampini if (j<temp_constraints) { 1837984c4197SStefano Zampini PetscInt ii; 1838984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); 1839674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1840c4303822SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Blas_LDA,correlation_mat,&Blas_LDB,&zero,temp_basis,&Blas_LDC)); 1841674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1842984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 1843674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 1844984c4197SStefano Zampini temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]=singular_vals[temp_constraints-1-k]*temp_basis[(temp_constraints-1-k)*size_of_constraint+ii]; 1845674ae819SStefano Zampini } 1846674ae819SStefano Zampini } 1847674ae819SStefano Zampini } 1848674ae819SStefano Zampini #else /* on missing GESVD */ 1849e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 1850e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 1851b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 1852674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1853674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1854e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,work,&lwork,&lierr)); 1855674ae819SStefano Zampini #else 1856e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,work,&lwork,rwork,&lierr)); 1857674ae819SStefano Zampini #endif 1858984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 1859674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1860984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 1861e310c8b4SStefano Zampini k = temp_constraints; 1862e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 1863674ae819SStefano Zampini j = 0; 1864e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 186545a1bb75SStefano Zampini valid_constraints = k-j; 1866911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 1867984c4197SStefano Zampini #endif /* on missing GESVD */ 1868674ae819SStefano Zampini } 1869a773dcb8SStefano Zampini } 187045a1bb75SStefano Zampini /* setting change_of_basis flag is safe now */ 187145a1bb75SStefano Zampini if (boolforchange) { 187245a1bb75SStefano Zampini for (j=0;j<valid_constraints;j++) { 187345a1bb75SStefano Zampini PetscBTSet(change_basis,total_counts-j-1); 187445a1bb75SStefano Zampini } 187545a1bb75SStefano Zampini } 1876674ae819SStefano Zampini } 1877674ae819SStefano Zampini /* free index sets of faces, edges and vertices */ 1878674ae819SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 1879674ae819SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 1880674ae819SStefano Zampini } 1881d06fc5fdSStefano Zampini if (n_ISForFaces) { 1882674ae819SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 1883d06fc5fdSStefano Zampini } 1884674ae819SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 1885674ae819SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 1886674ae819SStefano Zampini } 1887d06fc5fdSStefano Zampini if (n_ISForEdges) { 1888674ae819SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 1889d06fc5fdSStefano Zampini } 1890674ae819SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 189139e2fb2aSStefano Zampini /* map temp_indices_to_constraint in boundary numbering */ 18925e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,temp_indices[total_counts],temp_indices_to_constraint,&i,temp_indices_to_constraint_B);CHKERRQ(ierr); 189339e2fb2aSStefano Zampini if (i != temp_indices[total_counts]) { 189439e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",temp_indices[total_counts],i); 189539e2fb2aSStefano Zampini } 1896674ae819SStefano Zampini 1897984c4197SStefano Zampini /* free workspace */ 18988f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1899911cabfeSStefano Zampini ierr = PetscFree4(gidxs,permutation,temp_indices_to_constraint_work,temp_quadrature_constraint_work);CHKERRQ(ierr); 19008f1c130eSStefano Zampini } 19018f1c130eSStefano Zampini if (!skip_lapack) { 1902984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1903984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1904984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 1905984c4197SStefano Zampini #endif 1906984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 1907984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1908984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 1909984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 1910984c4197SStefano Zampini #endif 1911984c4197SStefano Zampini } 1912984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 1913984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 1914984c4197SStefano Zampini } 1915984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 1916984c4197SStefano Zampini 1917727cdba6SStefano Zampini /* set quantities in pcbddc data structure and store previous primal size */ 1918984c4197SStefano Zampini /* n_vertices defines the number of subdomain corners in the primal space */ 1919674ae819SStefano Zampini /* n_constraints defines the number of averages (they can be point primal dofs if change of basis is requested) */ 1920727cdba6SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 1921984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 1922674ae819SStefano Zampini pcbddc->n_vertices = n_vertices; 1923984c4197SStefano Zampini pcbddc->n_constraints = pcbddc->local_primal_size-pcbddc->n_vertices; 1924674ae819SStefano Zampini 1925674ae819SStefano Zampini /* Create constraint matrix */ 1926674ae819SStefano Zampini /* The constraint matrix is used to compute the l2g map of primal dofs */ 1927674ae819SStefano Zampini /* so we need to set it up properly either with or without change of basis */ 1928674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1929674ae819SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 1930984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 1931984c4197SStefano Zampini /* array to compute a local numbering of constraints : vertices first then constraints */ 1932785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_numbering);CHKERRQ(ierr); 1933984c4197SStefano Zampini /* array to select the proper local node (of minimum index with respect to global ordering) when changing the basis */ 1934984c4197SStefano Zampini /* note: it should not be needed since IS for faces and edges are already sorted by global ordering when analyzing the graph but... just in case */ 1935785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_minloc);CHKERRQ(ierr); 1936984c4197SStefano Zampini /* auxiliary stuff for basis change */ 1937785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&global_indices);CHKERRQ(ierr); 19384641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&touched);CHKERRQ(ierr); 1939984c4197SStefano Zampini 1940984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 1941984c4197SStefano Zampini total_primal_vertices=0; 1942984c4197SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1943674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 1944984c4197SStefano Zampini if (size_of_constraint == 1) { 19454641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]]);CHKERRQ(ierr); 1946984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]]; 1947984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=0; 1948984c4197SStefano Zampini total_primal_vertices++; 19494641a718SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { /* Same procedure used in PCBDDCGetPrimalConstraintsLocalIdx */ 1950984c4197SStefano Zampini PetscInt min_loc,min_index; 1951984c4197SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],global_indices);CHKERRQ(ierr); 1952984c4197SStefano Zampini /* find first untouched local node */ 1953674ae819SStefano Zampini k = 0; 19544641a718SStefano Zampini while (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) k++; 1955984c4197SStefano Zampini min_index = global_indices[k]; 1956984c4197SStefano Zampini min_loc = k; 1957984c4197SStefano Zampini /* search the minimum among global nodes already untouched on the cc */ 1958984c4197SStefano Zampini for (k=1;k<size_of_constraint;k++) { 1959984c4197SStefano Zampini /* there can be more than one constraint on a single connected component */ 19604641a718SStefano Zampini if (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k]) && min_index > global_indices[k]) { 1961984c4197SStefano Zampini min_index = global_indices[k]; 1962984c4197SStefano Zampini min_loc = k; 1963674ae819SStefano Zampini } 1964674ae819SStefano Zampini } 19654641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]+min_loc]);CHKERRQ(ierr); 1966984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]+min_loc]; 1967984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=min_loc; 1968984c4197SStefano Zampini total_primal_vertices++; 1969984c4197SStefano Zampini } 1970984c4197SStefano Zampini } 1971a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 1972a717540cSStefano Zampini qr_needed = PETSC_FALSE; 1973a717540cSStefano Zampini ierr = PetscBTCreate(pcbddc->local_primal_size,&qr_needed_idx);CHKERRQ(ierr); 1974a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 1975a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 1976fa434743SStefano Zampini if (!pcbddc->use_qr_single) { 1977a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 1978a717540cSStefano Zampini j = 0; 1979a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 1980a717540cSStefano Zampini if (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) { 1981a717540cSStefano Zampini j++; 1982a717540cSStefano Zampini } 1983a717540cSStefano Zampini } 1984a717540cSStefano Zampini /* found more than one primal dof on the cc */ 1985a717540cSStefano Zampini if (j > 1) { 1986a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 1987a717540cSStefano Zampini qr_needed = PETSC_TRUE; 1988a717540cSStefano Zampini } 1989fa434743SStefano Zampini } else { 1990fa434743SStefano Zampini PetscBTSet(qr_needed_idx,i); 1991fa434743SStefano Zampini qr_needed = PETSC_TRUE; 1992fa434743SStefano Zampini } 1993a717540cSStefano Zampini } 1994a717540cSStefano Zampini } 1995984c4197SStefano Zampini /* free workspace */ 1996984c4197SStefano Zampini ierr = PetscFree(global_indices);CHKERRQ(ierr); 199745a1bb75SStefano Zampini 1998674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 1999a717540cSStefano Zampini ierr = PetscSortInt(total_primal_vertices,aux_primal_numbering);CHKERRQ(ierr); 2000984c4197SStefano Zampini 2001984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 2002785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2003984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i]=1; 2004984c4197SStefano Zampini j=total_primal_vertices; 2005984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 20064641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2007674ae819SStefano Zampini nnz[j]=temp_indices[i+1]-temp_indices[i]; 2008674ae819SStefano Zampini j++; 2009674ae819SStefano Zampini } 2010674ae819SStefano Zampini } 2011674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2012674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2013674ae819SStefano Zampini /* set values in constraint matrix */ 2014984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 2015984c4197SStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,aux_primal_numbering[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2016674ae819SStefano Zampini } 2017984c4197SStefano Zampini total_counts = total_primal_vertices; 2018984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 20194641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2020674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2021674ae819SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&total_counts,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],&temp_quadrature_constraint[temp_indices[i]],INSERT_VALUES);CHKERRQ(ierr); 2022674ae819SStefano Zampini total_counts++; 2023674ae819SStefano Zampini } 2024674ae819SStefano Zampini } 2025674ae819SStefano Zampini /* assembling */ 2026674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2027674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2028984c4197SStefano Zampini /* 202945a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2030984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2031984c4197SStefano Zampini */ 2032674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2033674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2034026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2035984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2036026de310SStefano Zampini /* iterator on aux_primal_minloc (ordered as read from nearnullspace: vertices, edges and then constraints) */ 2037026de310SStefano Zampini PetscInt primal_counter; 2038984c4197SStefano Zampini /* working stuff for GEQRF */ 203981d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2040984c4197SStefano Zampini PetscBLASInt lqr_work; 2041984c4197SStefano Zampini /* working stuff for UNGQR */ 2042984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2043984c4197SStefano Zampini PetscBLASInt lgqr_work; 2044984c4197SStefano Zampini /* working stuff for TRTRS */ 2045984c4197SStefano Zampini PetscScalar *trs_rhs; 20463f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2047984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2048984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2049984c4197SStefano Zampini PetscScalar *start_vals; 2050984c4197SStefano Zampini /* working stuff for values insertion */ 20514641a718SStefano Zampini PetscBT is_primal; 2052906d46d4SStefano Zampini /* matrix sizes */ 2053906d46d4SStefano Zampini PetscInt global_size,local_size; 2054906d46d4SStefano Zampini /* work array for nonzeros */ 2055906d46d4SStefano Zampini PetscScalar *nnz_array; 2056906d46d4SStefano Zampini /* temporary change of basis */ 2057906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2058906d46d4SStefano Zampini /* auxiliary work for global change of basis */ 2059906d46d4SStefano Zampini Vec nnz_vec; 206022bc73bbSStefano Zampini PetscInt *idxs_I,*idxs_B,*idxs_all,*d_nnz,*o_nnz; 2061906d46d4SStefano Zampini PetscInt nvtxs,*xadj,*adjncy,*idxs_mapped; 2062906d46d4SStefano Zampini PetscScalar *vals; 2063906d46d4SStefano Zampini PetscBool done; 2064984c4197SStefano Zampini 2065906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2066906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 2067906d46d4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,impMatType);CHKERRQ(ierr); 2068906d46d4SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n_B,pcis->n_B,pcis->n_B,pcis->n_B);CHKERRQ(ierr); 2069906d46d4SStefano Zampini 2070906d46d4SStefano Zampini /* nonzeros for local mat */ 2071785e854fSJed Brown ierr = PetscMalloc1(pcis->n_B,&nnz);CHKERRQ(ierr); 2072a717540cSStefano Zampini for (i=0;i<pcis->n_B;i++) nnz[i]=1; 2073a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 2074a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 2075a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2076a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 2077a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint_B[temp_indices[i]+j]] = size_of_constraint; 2078a717540cSStefano Zampini } else { 2079a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint_B[temp_indices[i]+j]] = 2; 2080a717540cSStefano Zampini /* get local primal index on the cc */ 2081a717540cSStefano Zampini j = 0; 2082a717540cSStefano Zampini while (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+j])) j++; 2083a717540cSStefano Zampini nnz[temp_indices_to_constraint_B[temp_indices[i]+j]] = size_of_constraint; 2084a717540cSStefano Zampini } 2085a717540cSStefano Zampini } 2086a717540cSStefano Zampini } 2087906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2088a717540cSStefano Zampini /* Set initial identity in the matrix */ 2089a717540cSStefano Zampini for (i=0;i<pcis->n_B;i++) { 2090906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 2091a717540cSStefano Zampini } 2092a717540cSStefano Zampini 2093a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2094a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2095a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2096a717540cSStefano Zampini } 2097a717540cSStefano Zampini 2098a717540cSStefano Zampini 2099a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 2100a717540cSStefano Zampini /* 2101a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 2102a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 2103a717540cSStefano Zampini 2104a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 2105a717540cSStefano Zampini 2106a6b551f4SStefano 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) 2107a6b551f4SStefano Zampini 2108a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 2109a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 2110a717540cSStefano Zampini | ... | 2111a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 2112a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 2113a717540cSStefano Zampini 2114a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 2115a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 2116a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 2117a6b551f4SStefano Zampini 2118a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 2119a717540cSStefano Zampini */ 2120a717540cSStefano Zampini if (qr_needed) { 2121984c4197SStefano Zampini /* space to store Q */ 2122854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 2123984c4197SStefano Zampini /* first we issue queries for optimal work */ 21243f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 21253f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 21263f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2127984c4197SStefano Zampini lqr_work = -1; 21283f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 2129984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 2130984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 2131785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 2132984c4197SStefano Zampini lgqr_work = -1; 21333f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 21343f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 21353f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 21363f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 21373f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 21383f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 2139984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 2140984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 2141785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 2142984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 2143785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 2144984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 2145785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 2146a717540cSStefano Zampini /* allocating workspace for check */ 2147a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2148785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&work);CHKERRQ(ierr); 2149a717540cSStefano Zampini } 2150a717540cSStefano Zampini } 2151984c4197SStefano Zampini /* array to store whether a node is primal or not */ 21524641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 2153473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 21545e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,aux_primal_numbering,&i,aux_primal_numbering_B);CHKERRQ(ierr); 215539e2fb2aSStefano Zampini if (i != total_primal_vertices) { 215639e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 21574641a718SStefano Zampini } 215839e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 215939e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 216039e2fb2aSStefano Zampini } 216139e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 2162984c4197SStefano Zampini 2163a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 2164026de310SStefano Zampini /* -> using implicit ordering contained in temp_indices data */ 2165026de310SStefano Zampini total_counts = pcbddc->n_vertices; 2166026de310SStefano Zampini primal_counter = total_counts; 2167026de310SStefano Zampini while (total_counts<pcbddc->local_primal_size) { 2168026de310SStefano Zampini primal_dofs = 1; 21694641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 2170026de310SStefano Zampini /* get all constraints with same support: if more then one constraint is present on the cc then surely indices are stored contiguosly */ 2171026de310SStefano Zampini while (total_counts+primal_dofs < pcbddc->local_primal_size && temp_indices_to_constraint_B[temp_indices[total_counts]] == temp_indices_to_constraint_B[temp_indices[total_counts+primal_dofs]]) { 2172026de310SStefano Zampini primal_dofs++; 2173674ae819SStefano Zampini } 2174984c4197SStefano Zampini /* get constraint info */ 2175026de310SStefano Zampini size_of_constraint = temp_indices[total_counts+1]-temp_indices[total_counts]; 2176984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 2177984c4197SStefano Zampini 2178984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2179a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraints %d to %d (incl) need a change of basis (size %d)\n",total_counts,total_counts+primal_dofs-1,size_of_constraint);CHKERRQ(ierr); 2180674ae819SStefano Zampini } 2181984c4197SStefano Zampini 2182fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 2183a717540cSStefano Zampini 2184a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 2185a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2186a717540cSStefano Zampini ierr = PetscMemcpy(work,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2187a717540cSStefano Zampini } 2188984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 2189026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2190984c4197SStefano Zampini 2191984c4197SStefano Zampini /* compute QR decomposition of constraints */ 21923f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 21933f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 21943f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2195674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 21963f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 2197984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 2198674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2199984c4197SStefano Zampini 2200984c4197SStefano Zampini /* explictly compute R^-T */ 2201984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 2202984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 22033f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 22043f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 22053f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 22063f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 2207984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 22083f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 2209984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 2210984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2211984c4197SStefano Zampini 2212a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 22133f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 22143f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 22153f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 22163f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2217984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 22183f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 2219984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 2220984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2221984c4197SStefano Zampini 2222984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 2223984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 2224984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 22253f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 22263f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 22273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 22283f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 22293f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 22303f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2231984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2232c4303822SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&zero,&temp_quadrature_constraint[temp_indices[total_counts]],&Blas_LDC)); 2233984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2234026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2235984c4197SStefano Zampini 2236984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 2237026de310SStefano Zampini start_rows = &temp_indices_to_constraint_B[temp_indices[total_counts]]; 2238984c4197SStefano Zampini /* insert cols for primal dofs */ 2239984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 2240984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 2241026de310SStefano Zampini start_cols = &temp_indices_to_constraint_B[temp_indices[total_counts]+aux_primal_minloc[primal_counter+j]]; 2242906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2243984c4197SStefano Zampini } 2244984c4197SStefano Zampini /* insert cols for dual dofs */ 2245984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 22464641a718SStefano Zampini if (!PetscBTLookup(is_primal,temp_indices_to_constraint_B[temp_indices[total_counts]+k])) { 2247984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 2248026de310SStefano Zampini start_cols = &temp_indices_to_constraint_B[temp_indices[total_counts]+k]; 2249906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2250984c4197SStefano Zampini j++; 2251674ae819SStefano Zampini } 2252674ae819SStefano Zampini } 2253984c4197SStefano Zampini 2254984c4197SStefano Zampini /* check change of basis */ 2255984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2256984c4197SStefano Zampini PetscInt ii,jj; 2257984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 2258c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 2259c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2260c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 2261c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2262c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 2263c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 2264984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2265c4303822SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&Blas_M,&Blas_N,&Blas_K,&one,work,&Blas_LDA,qr_basis,&Blas_LDB,&zero,&work[size_of_constraint*primal_dofs],&Blas_LDC)); 2266984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2267984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2268984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2269984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 2270984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 2271674ae819SStefano Zampini } 2272674ae819SStefano Zampini } 2273984c4197SStefano Zampini if (!valid_qr) { 227422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 2275984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2276984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2277984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 2278984c4197SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 2279674ae819SStefano Zampini } 2280984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 2281984c4197SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 2282984c4197SStefano Zampini } 2283984c4197SStefano Zampini } 2284984c4197SStefano Zampini } 2285674ae819SStefano Zampini } else { 228622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 2287674ae819SStefano Zampini } 2288674ae819SStefano Zampini } 2289a717540cSStefano Zampini } else { /* simple transformation block */ 2290a717540cSStefano Zampini PetscInt row,col; 2291a6b551f4SStefano Zampini PetscScalar val,norm; 2292a6b551f4SStefano Zampini 2293a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2294a6b551f4SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,temp_quadrature_constraint+temp_indices[total_counts],&Blas_one,temp_quadrature_constraint+temp_indices[total_counts],&Blas_one)); 2295a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2296a717540cSStefano Zampini row = temp_indices_to_constraint_B[temp_indices[total_counts]+j]; 2297a717540cSStefano Zampini if (!PetscBTLookup(is_primal,row)) { 2298a717540cSStefano Zampini col = temp_indices_to_constraint_B[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2299906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 2300a6b551f4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,temp_quadrature_constraint[temp_indices[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 2301a717540cSStefano Zampini } else { 2302a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 2303a717540cSStefano Zampini col = temp_indices_to_constraint_B[temp_indices[total_counts]+k]; 2304a717540cSStefano Zampini if (row != col) { 2305a717540cSStefano Zampini val = -temp_quadrature_constraint[temp_indices[total_counts]+k]/temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2306a717540cSStefano Zampini } else { 2307a6b551f4SStefano Zampini val = temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]/norm; 2308a717540cSStefano Zampini } 2309906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 2310a717540cSStefano Zampini } 2311a717540cSStefano Zampini } 2312a717540cSStefano Zampini } 231398a51de6SStefano Zampini if (pcbddc->dbg_flag) { 231422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 2315a717540cSStefano Zampini } 2316674ae819SStefano Zampini } 2317026de310SStefano Zampini /* increment primal counter */ 2318026de310SStefano Zampini primal_counter += primal_dofs; 2319984c4197SStefano Zampini } else { 2320984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2321026de310SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraint %d does not need a change of basis (size %d)\n",total_counts,temp_indices[total_counts+1]-temp_indices[total_counts]);CHKERRQ(ierr); 2322674ae819SStefano Zampini } 2323674ae819SStefano Zampini } 2324026de310SStefano Zampini /* increment constraint counter total_counts */ 2325026de310SStefano Zampini total_counts += primal_dofs; 2326674ae819SStefano Zampini } 2327a717540cSStefano Zampini 2328a717540cSStefano Zampini /* free workspace */ 2329a717540cSStefano Zampini if (qr_needed) { 2330984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2331984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2332984c4197SStefano Zampini } 2333984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 2334984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 2335984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 2336984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 2337984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 2338674ae819SStefano Zampini } 2339a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 2340906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2341906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2342906d46d4SStefano Zampini 2343906d46d4SStefano Zampini /* assembling of global change of variable */ 2344906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2345906d46d4SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2346906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2347906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2348906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2349906d46d4SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->ChangeOfBasisMatrix,matis->mapping,matis->mapping);CHKERRQ(ierr); 2350906d46d4SStefano Zampini 2351906d46d4SStefano Zampini /* nonzeros (overestimated) */ 2352906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&nnz_vec);CHKERRQ(ierr); 2353906d46d4SStefano Zampini ierr = VecSetLocalToGlobalMapping(nnz_vec,matis->mapping);CHKERRQ(ierr); 2354906d46d4SStefano Zampini ierr = PetscMalloc2(pcis->n,&nnz_array,pcis->n,&idxs_all);CHKERRQ(ierr); 2355906d46d4SStefano Zampini for (i=0;i<pcis->n;i++) { 2356906d46d4SStefano Zampini nnz_array[i] = 1.0; 2357906d46d4SStefano Zampini idxs_all[i] = i; 2358906d46d4SStefano Zampini } 2359906d46d4SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&idxs_B);CHKERRQ(ierr); 2360906d46d4SStefano Zampini for (i=0;i<pcis->n_B;i++) { 2361906d46d4SStefano Zampini nnz_array[idxs_B[i]] = nnz[i]; 2362906d46d4SStefano Zampini } 2363a5187659SStefano Zampini if (pcis->n) { 2364906d46d4SStefano Zampini ierr = VecSetValuesLocal(nnz_vec,pcis->n,idxs_all,nnz_array,INSERT_VALUES);CHKERRQ(ierr); 2365a5187659SStefano Zampini } 2366906d46d4SStefano Zampini ierr = VecAssemblyBegin(nnz_vec);CHKERRQ(ierr); 2367906d46d4SStefano Zampini ierr = VecAssemblyEnd(nnz_vec);CHKERRQ(ierr); 2368906d46d4SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2369906d46d4SStefano Zampini ierr = PetscFree2(nnz_array,idxs_all);CHKERRQ(ierr); 237022bc73bbSStefano Zampini ierr = PetscMalloc2(local_size,&d_nnz,local_size,&o_nnz);CHKERRQ(ierr); 2371906d46d4SStefano Zampini ierr = VecGetArray(nnz_vec,&nnz_array);CHKERRQ(ierr); 2372906d46d4SStefano Zampini for (i=0;i<local_size;i++) { 237322bc73bbSStefano Zampini d_nnz[i] = PetscMin((PetscInt)(PetscRealPart(nnz_array[i])),local_size); 237422bc73bbSStefano Zampini o_nnz[i] = PetscMin((PetscInt)(PetscRealPart(nnz_array[i])),global_size-local_size); 2375906d46d4SStefano Zampini } 2376906d46d4SStefano Zampini ierr = VecRestoreArray(nnz_vec,&nnz_array);CHKERRQ(ierr); 2377906d46d4SStefano Zampini ierr = VecDestroy(&nnz_vec);CHKERRQ(ierr); 237822bc73bbSStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->ChangeOfBasisMatrix,0,d_nnz,0,o_nnz);CHKERRQ(ierr); 237922bc73bbSStefano Zampini ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); 2380906d46d4SStefano Zampini 2381906d46d4SStefano Zampini /* Set identity on dirichlet dofs */ 2382906d46d4SStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&idxs_I);CHKERRQ(ierr); 2383906d46d4SStefano Zampini for (i=0;i<pcis->n-pcis->n_B;i++) { 2384906d46d4SStefano Zampini PetscScalar one=1.0; 2385906d46d4SStefano Zampini ierr = MatSetValuesLocal(pcbddc->ChangeOfBasisMatrix,1,idxs_I+i,1,idxs_I+i,&one,INSERT_VALUES);CHKERRQ(ierr); 2386906d46d4SStefano Zampini } 2387906d46d4SStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&idxs_I);CHKERRQ(ierr); 2388906d46d4SStefano Zampini 2389906d46d4SStefano Zampini /* Set values at interface dofs */ 2390906d46d4SStefano Zampini done = PETSC_TRUE; 2391906d46d4SStefano Zampini ierr = MatGetRowIJ(localChangeOfBasisMatrix,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2392906d46d4SStefano Zampini if (!done) { 2393906d46d4SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 2394906d46d4SStefano Zampini } 2395906d46d4SStefano Zampini ierr = MatSeqAIJGetArray(localChangeOfBasisMatrix,&vals);CHKERRQ(ierr); 2396906d46d4SStefano Zampini ierr = PetscMalloc1(xadj[nvtxs],&idxs_mapped);CHKERRQ(ierr); 23975e8657edSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->BtoNmap,xadj[nvtxs],adjncy,idxs_mapped);CHKERRQ(ierr); 2398906d46d4SStefano Zampini for (i=0;i<nvtxs;i++) { 2399906d46d4SStefano Zampini PetscInt row,*cols,ncols; 2400906d46d4SStefano Zampini PetscScalar *mat_vals; 2401906d46d4SStefano Zampini 2402906d46d4SStefano Zampini row = idxs_B[i]; 2403906d46d4SStefano Zampini ncols = xadj[i+1]-xadj[i]; 2404906d46d4SStefano Zampini cols = idxs_mapped+xadj[i]; 2405906d46d4SStefano Zampini mat_vals = vals+xadj[i]; 2406906d46d4SStefano Zampini ierr = MatSetValuesLocal(pcbddc->ChangeOfBasisMatrix,1,&row,ncols,cols,mat_vals,INSERT_VALUES);CHKERRQ(ierr); 2407906d46d4SStefano Zampini } 2408906d46d4SStefano Zampini ierr = MatRestoreRowIJ(localChangeOfBasisMatrix,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2409906d46d4SStefano Zampini if (!done) { 2410906d46d4SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 2411906d46d4SStefano Zampini } 2412906d46d4SStefano Zampini ierr = MatSeqAIJRestoreArray(localChangeOfBasisMatrix,&vals);CHKERRQ(ierr); 2413906d46d4SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&idxs_B);CHKERRQ(ierr); 2414906d46d4SStefano Zampini ierr = PetscFree(idxs_mapped);CHKERRQ(ierr); 2415674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2416674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2417906d46d4SStefano Zampini 2418906d46d4SStefano Zampini /* check */ 2419906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2420906d46d4SStefano Zampini PetscReal error; 2421906d46d4SStefano Zampini Vec x,x_change; 2422906d46d4SStefano Zampini 2423906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 2424906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 2425906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2426906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 2427906d46d4SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2428906d46d4SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2429906d46d4SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 2430906d46d4SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2431906d46d4SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2432906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 2433906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2434906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2435906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2436906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on B: %1.6e\n",error);CHKERRQ(ierr); 2437906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2438906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2439906d46d4SStefano Zampini } 2440b96c3477SStefano Zampini 2441b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 2442b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2443b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 2444b96c3477SStefano Zampini if (sub_schurs->n_subs_par_g) { 2445*b7eb3628SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Change of basis with deluxe scaling and parallel problems still needs to be implemented"); 2446b96c3477SStefano Zampini } 2447b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 2448b96c3477SStefano Zampini Mat S_1,S_2,tmat; 2449b96c3477SStefano Zampini ierr = MatGetSubMatrixUnsorted(localChangeOfBasisMatrix,sub_schurs->is_Ej_all,sub_schurs->is_Ej_all,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 2450b96c3477SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_1);CHKERRQ(ierr); 2451b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 2452b96c3477SStefano Zampini sub_schurs->S_Ej_all = S_1; 2453b96c3477SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_2);CHKERRQ(ierr); 2454b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 2455b96c3477SStefano Zampini sub_schurs->sum_S_Ej_all = S_2; 2456b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2457b96c3477SStefano Zampini } 2458b96c3477SStefano Zampini } 2459906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 2460906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 2461b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2462b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 2463b9b85e73SStefano Zampini } 2464906d46d4SStefano Zampini 2465906d46d4SStefano Zampini /* set up change of basis context */ 2466906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2467906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 2468906d46d4SStefano Zampini 2469906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 2470906d46d4SStefano Zampini PetscInt global_size,local_size; 2471906d46d4SStefano Zampini 2472906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2473906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2474906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 2475906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2476906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 2477906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 2478906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 2479906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 2480906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 2481906d46d4SStefano Zampini } else { 2482906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 2483906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 2484906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 2485906d46d4SStefano Zampini } 2486906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 2487906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2488906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 2489906d46d4SStefano Zampini } else { 2490906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2491906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 2492906d46d4SStefano Zampini } 2493906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 2494906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 2495906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2496906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2497b9b85e73SStefano Zampini } 2498a717540cSStefano Zampini 2499727cdba6SStefano Zampini /* get indices in local ordering for vertices and constraints */ 2500727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { /* if this is true, I need to check if a new primal space has been introduced */ 2501473ba861SJed Brown ierr = PetscMalloc1(olocal_primal_size,&oprimal_indices_local_idxs);CHKERRQ(ierr); 2502727cdba6SStefano Zampini ierr = PetscMemcpy(oprimal_indices_local_idxs,pcbddc->primal_indices_local_idxs,olocal_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 2503727cdba6SStefano Zampini } 2504727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2505f347579bSStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2506473ba861SJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2507727cdba6SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_primal_numbering);CHKERRQ(ierr); 2508727cdba6SStefano Zampini ierr = PetscMemcpy(pcbddc->primal_indices_local_idxs,aux_primal_numbering,i*sizeof(PetscInt));CHKERRQ(ierr); 2509727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2510727cdba6SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_primal_numbering);CHKERRQ(ierr); 2511727cdba6SStefano Zampini ierr = PetscMemcpy(&pcbddc->primal_indices_local_idxs[i],aux_primal_numbering,j*sizeof(PetscInt));CHKERRQ(ierr); 2512727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2513e9189074SStefano Zampini /* set quantities in PCBDDC data struct */ 2514e9189074SStefano Zampini pcbddc->n_actual_vertices = i; 2515727cdba6SStefano Zampini /* check if a new primal space has been introduced */ 2516727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 2517727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 2518727cdba6SStefano Zampini ierr = PetscMemcmp(pcbddc->primal_indices_local_idxs,oprimal_indices_local_idxs,olocal_primal_size,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 2519c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 2520727cdba6SStefano Zampini ierr = PetscFree(oprimal_indices_local_idxs);CHKERRQ(ierr); 2521727cdba6SStefano Zampini } 2522727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 2523727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2524727cdba6SStefano Zampini 2525a717540cSStefano Zampini /* flush dbg viewer */ 2526b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 2527b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2528b8ffe317SStefano Zampini } 2529a717540cSStefano Zampini 2530e310c8b4SStefano Zampini /* free workspace */ 2531a717540cSStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 2532a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 2533984c4197SStefano Zampini ierr = PetscFree(aux_primal_minloc);CHKERRQ(ierr); 25344641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 2535906d46d4SStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 2536906d46d4SStefano Zampini ierr = PetscFree3(temp_quadrature_constraint,temp_indices_to_constraint,temp_indices_to_constraint_B);CHKERRQ(ierr); 2537674ae819SStefano Zampini PetscFunctionReturn(0); 2538674ae819SStefano Zampini } 2539674ae819SStefano Zampini 2540674ae819SStefano Zampini #undef __FUNCT__ 2541674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 2542674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 2543674ae819SStefano Zampini { 2544674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2545674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2546674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 254763602bcaSStefano Zampini PetscInt ierr,i,vertex_size; 2548674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2549674ae819SStefano Zampini 2550674ae819SStefano Zampini PetscFunctionBegin; 25518e61c736SStefano Zampini /* Reset previously computed graph */ 25528e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 2553674ae819SStefano Zampini /* Init local Graph struct */ 2554674ae819SStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,matis->mapping);CHKERRQ(ierr); 2555674ae819SStefano Zampini 2556575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 2557575ad6abSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 2558575ad6abSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2559575ad6abSStefano Zampini } 25609577ea80SStefano Zampini 2561674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 25624d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 2563674ae819SStefano Zampini Mat mat_adj; 25644d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 25654d379d7bSStefano Zampini PetscInt nvtxs; 2566674ae819SStefano Zampini PetscBool flg_row=PETSC_TRUE; 2567674ae819SStefano Zampini 2568674ae819SStefano Zampini ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 25694d379d7bSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2570674ae819SStefano Zampini if (!flg_row) { 2571674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 2572674ae819SStefano Zampini } 25734d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 25744d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 2575b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 25764d379d7bSStefano Zampini } else { /* just compute subdomain's connected components */ 25774d379d7bSStefano Zampini IS is_dummy; 25784d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 25794d379d7bSStefano Zampini PetscInt j,sum; 25804d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 25814d379d7bSStefano Zampini const PetscInt *idxs; 25824d379d7bSStefano Zampini PCBDDCGraph graph; 25834d379d7bSStefano Zampini PetscBT is_on_boundary; 25844d379d7bSStefano Zampini 25854d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 25864d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 25874d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 25884d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 25894d379d7bSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy);CHKERRQ(ierr); 25904d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 25914d379d7bSStefano Zampini graph->xadj = xadj; 25924d379d7bSStefano Zampini graph->adjncy = adjncy; 25934d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 25944d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 25954d379d7bSStefano Zampini 25964d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 25974d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains\n",PetscGlobalRank,graph->ncc);CHKERRQ(ierr); 25984d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 25994d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 26004d379d7bSStefano Zampini } 26014d379d7bSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 26024d379d7bSStefano Zampini } 26034d379d7bSStefano Zampini 26044d379d7bSStefano Zampini ierr = PetscBTCreate(nvtxs,&is_on_boundary);CHKERRQ(ierr); 26054d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 26064d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 26074d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 26084d379d7bSStefano Zampini } 26094d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 26104d379d7bSStefano Zampini 26114d379d7bSStefano Zampini ierr = PetscCalloc1(nvtxs+1,&cxadj);CHKERRQ(ierr); 26124d379d7bSStefano Zampini sum = 0; 26134d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 26144d379d7bSStefano Zampini PetscInt sizecc = 0; 26154d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 26164d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 26174d379d7bSStefano Zampini sizecc++; 26184d379d7bSStefano Zampini } 26194d379d7bSStefano Zampini } 26204d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 26214d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 26224d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 26234d379d7bSStefano Zampini } 26244d379d7bSStefano Zampini } 26254d379d7bSStefano Zampini sum += sizecc*sizecc; 26264d379d7bSStefano Zampini } 26274d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 26284d379d7bSStefano Zampini sum = 0; 26294d379d7bSStefano Zampini for (i=0;i<nvtxs;i++) { 26304d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 26314d379d7bSStefano Zampini cxadj[i] = sum; 26324d379d7bSStefano Zampini sum += temp; 26334d379d7bSStefano Zampini } 26344d379d7bSStefano Zampini cxadj[nvtxs] = sum; 26354d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 26364d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 26374d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 26384d379d7bSStefano Zampini PetscInt k,sizecc = 0; 26394d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 26404d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 26414d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 26424d379d7bSStefano Zampini sizecc++; 26434d379d7bSStefano Zampini } 26444d379d7bSStefano Zampini } 26454d379d7bSStefano Zampini } 26464d379d7bSStefano Zampini } 26474d379d7bSStefano Zampini } 26484d379d7bSStefano Zampini if (nvtxs) { 26494d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 26504d379d7bSStefano Zampini } else { 26514d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 26524d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 26534d379d7bSStefano Zampini } 26544d379d7bSStefano Zampini graph->xadj = 0; 26554d379d7bSStefano Zampini graph->adjncy = 0; 26564d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 26574d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 26584d379d7bSStefano Zampini } 26594d379d7bSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2660674ae819SStefano Zampini if (!flg_row) { 2661674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 2662674ae819SStefano Zampini } 2663674ae819SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2664674ae819SStefano Zampini } 2665674ae819SStefano Zampini 266663602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 2667674ae819SStefano Zampini vertex_size = 1; 266863602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 266963602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 267095ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 267163602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 2672a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 267363602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2674674ae819SStefano Zampini } 267563602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 267663602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 267763602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 2678674ae819SStefano Zampini } 267963602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 2680674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 268163602bcaSStefano Zampini } else { 268263602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 268363602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 2684854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 268563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 268663602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 268763602bcaSStefano Zampini } 268863602bcaSStefano Zampini } 2689674ae819SStefano Zampini } 2690674ae819SStefano Zampini 2691674ae819SStefano Zampini /* Setup of Graph */ 2692785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 2693a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 2694785d1243SStefano Zampini } 2695785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 2696a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2697785d1243SStefano Zampini } 269863602bcaSStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices); 2699674ae819SStefano Zampini 2700674ae819SStefano Zampini /* Graph's connected components analysis */ 2701674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 2702674ae819SStefano Zampini 2703674ae819SStefano Zampini /* print some info to stdout */ 2704674ae819SStefano Zampini if (pcbddc->dbg_flag) { 2705e49050b4SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer); 2706674ae819SStefano Zampini } 2707fb180af4SStefano Zampini 2708fb180af4SStefano Zampini /* mark topography has done */ 2709fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 2710674ae819SStefano Zampini PetscFunctionReturn(0); 2711674ae819SStefano Zampini } 2712674ae819SStefano Zampini 2713674ae819SStefano Zampini #undef __FUNCT__ 2714674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalVerticesLocalIdx" 2715f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIdx(PC pc, PetscInt *n_vertices, PetscInt **vertices_idx) 2716674ae819SStefano Zampini { 2717674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2718674ae819SStefano Zampini PetscInt *vertices,*row_cmat_indices,n,i,size_of_constraint,local_primal_size; 2719674ae819SStefano Zampini PetscErrorCode ierr; 2720674ae819SStefano Zampini 2721674ae819SStefano Zampini PetscFunctionBegin; 2722674ae819SStefano Zampini n = 0; 2723674ae819SStefano Zampini vertices = 0; 2724674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 2725674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&i);CHKERRQ(ierr); 2726b120a5c6SStefano Zampini for (i=0;i<local_primal_size;i++) { 2727b120a5c6SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2728b120a5c6SStefano Zampini if (size_of_constraint == 1) n++; 2729b120a5c6SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2730b120a5c6SStefano Zampini } 2731811e8ca2SStefano Zampini if (vertices_idx) { 2732785e854fSJed Brown ierr = PetscMalloc1(n,&vertices);CHKERRQ(ierr); 2733b120a5c6SStefano Zampini n = 0; 2734674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2735674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2736674ae819SStefano Zampini if (size_of_constraint == 1) { 2737674ae819SStefano Zampini vertices[n++]=row_cmat_indices[0]; 2738674ae819SStefano Zampini } 2739674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2740674ae819SStefano Zampini } 2741674ae819SStefano Zampini } 2742811e8ca2SStefano Zampini } 2743674ae819SStefano Zampini *n_vertices = n; 2744811e8ca2SStefano Zampini if (vertices_idx) *vertices_idx = vertices; 2745674ae819SStefano Zampini PetscFunctionReturn(0); 2746674ae819SStefano Zampini } 2747674ae819SStefano Zampini 2748674ae819SStefano Zampini #undef __FUNCT__ 2749674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalConstraintsLocalIdx" 2750f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalConstraintsLocalIdx(PC pc, PetscInt *n_constraints, PetscInt **constraints_idx) 2751674ae819SStefano Zampini { 2752674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2753674ae819SStefano Zampini PetscInt *constraints_index,*row_cmat_indices,*row_cmat_global_indices; 2754674ae819SStefano Zampini PetscInt n,i,j,size_of_constraint,local_primal_size,local_size,max_size_of_constraint,min_index,min_loc; 27554641a718SStefano Zampini PetscBT touched; 2756674ae819SStefano Zampini PetscErrorCode ierr; 2757674ae819SStefano Zampini 2758f34684f1SStefano Zampini /* This function assumes that the number of local constraints per connected component 2759f34684f1SStefano Zampini is not greater than the number of nodes defined for the connected component 2760f34684f1SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 2761674ae819SStefano Zampini PetscFunctionBegin; 2762674ae819SStefano Zampini n = 0; 2763674ae819SStefano Zampini constraints_index = 0; 2764674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 2765674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&local_size);CHKERRQ(ierr); 2766674ae819SStefano Zampini max_size_of_constraint = 0; 2767674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2768674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2769674ae819SStefano Zampini if (size_of_constraint > 1) { 2770674ae819SStefano Zampini n++; 2771674ae819SStefano Zampini } 2772674ae819SStefano Zampini max_size_of_constraint = PetscMax(size_of_constraint,max_size_of_constraint); 2773674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2774674ae819SStefano Zampini } 2775811e8ca2SStefano Zampini if (constraints_idx) { 2776785e854fSJed Brown ierr = PetscMalloc1(n,&constraints_index);CHKERRQ(ierr); 2777785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&row_cmat_global_indices);CHKERRQ(ierr); 27784641a718SStefano Zampini ierr = PetscBTCreate(local_size,&touched);CHKERRQ(ierr); 2779674ae819SStefano Zampini n = 0; 2780674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2781674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2782674ae819SStefano Zampini if (size_of_constraint > 1) { 2783674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,row_cmat_indices,row_cmat_global_indices);CHKERRQ(ierr); 278482d3d8afSStefano Zampini /* find first untouched local node */ 278582d3d8afSStefano Zampini j = 0; 27864641a718SStefano Zampini while (PetscBTLookup(touched,row_cmat_indices[j])) j++; 278782d3d8afSStefano Zampini min_index = row_cmat_global_indices[j]; 278882d3d8afSStefano Zampini min_loc = j; 278982d3d8afSStefano Zampini /* search the minimum among nodes not yet touched on the connected component 279082d3d8afSStefano Zampini since there can be more than one constraint on a single cc */ 2791674ae819SStefano Zampini for (j=1;j<size_of_constraint;j++) { 27924641a718SStefano Zampini if (!PetscBTLookup(touched,row_cmat_indices[j]) && min_index > row_cmat_global_indices[j]) { 2793674ae819SStefano Zampini min_index = row_cmat_global_indices[j]; 2794674ae819SStefano Zampini min_loc = j; 2795674ae819SStefano Zampini } 2796674ae819SStefano Zampini } 27974641a718SStefano Zampini ierr = PetscBTSet(touched,row_cmat_indices[min_loc]);CHKERRQ(ierr); 2798674ae819SStefano Zampini constraints_index[n++] = row_cmat_indices[min_loc]; 2799674ae819SStefano Zampini } 2800674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2801674ae819SStefano Zampini } 28024641a718SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 2803674ae819SStefano Zampini ierr = PetscFree(row_cmat_global_indices);CHKERRQ(ierr); 2804811e8ca2SStefano Zampini } 2805811e8ca2SStefano Zampini } 2806674ae819SStefano Zampini *n_constraints = n; 2807811e8ca2SStefano Zampini if (constraints_idx) *constraints_idx = constraints_index; 2808674ae819SStefano Zampini PetscFunctionReturn(0); 2809674ae819SStefano Zampini } 2810674ae819SStefano Zampini 2811674ae819SStefano Zampini #undef __FUNCT__ 2812674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 2813674ae819SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(MPI_Comm comm,ISLocalToGlobalMapping l2gmap, PetscInt n_local_dofs, PetscInt local_dofs[], PetscInt local_dofs_mult[], PetscInt* n_global_subset, PetscInt* global_numbering_subset[]) 2814674ae819SStefano Zampini { 2815674ae819SStefano Zampini Vec local_vec,global_vec; 2816674ae819SStefano Zampini IS seqis,paris; 2817674ae819SStefano Zampini VecScatter scatter_ctx; 2818674ae819SStefano Zampini PetscScalar *array; 2819674ae819SStefano Zampini PetscInt *temp_global_dofs; 2820674ae819SStefano Zampini PetscScalar globalsum; 2821674ae819SStefano Zampini PetscInt i,j,s; 2822674ae819SStefano Zampini PetscInt nlocals,first_index,old_index,max_local; 2823674ae819SStefano Zampini PetscMPIInt rank_prec_comm,size_prec_comm,max_global; 2824674ae819SStefano Zampini PetscMPIInt *dof_sizes,*dof_displs; 2825674ae819SStefano Zampini PetscBool first_found; 2826674ae819SStefano Zampini PetscErrorCode ierr; 2827674ae819SStefano Zampini 2828674ae819SStefano Zampini PetscFunctionBegin; 2829674ae819SStefano Zampini /* mpi buffers */ 2830b9b85e73SStefano Zampini ierr = MPI_Comm_size(comm,&size_prec_comm);CHKERRQ(ierr); 2831b9b85e73SStefano Zampini ierr = MPI_Comm_rank(comm,&rank_prec_comm);CHKERRQ(ierr); 2832674ae819SStefano Zampini j = ( !rank_prec_comm ? size_prec_comm : 0); 2833785e854fSJed Brown ierr = PetscMalloc1(j,&dof_sizes);CHKERRQ(ierr); 2834785e854fSJed Brown ierr = PetscMalloc1(j,&dof_displs);CHKERRQ(ierr); 2835674ae819SStefano Zampini /* get maximum size of subset */ 2836785e854fSJed Brown ierr = PetscMalloc1(n_local_dofs,&temp_global_dofs);CHKERRQ(ierr); 2837674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2gmap,n_local_dofs,local_dofs,temp_global_dofs);CHKERRQ(ierr); 2838674ae819SStefano Zampini max_local = 0; 2839b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2840674ae819SStefano Zampini if (max_local < temp_global_dofs[i] ) { 2841674ae819SStefano Zampini max_local = temp_global_dofs[i]; 2842674ae819SStefano Zampini } 2843674ae819SStefano Zampini } 2844b9b85e73SStefano Zampini ierr = MPI_Allreduce(&max_local,&max_global,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 2845674ae819SStefano Zampini max_global++; 2846674ae819SStefano Zampini max_local = 0; 2847b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2848674ae819SStefano Zampini if (max_local < local_dofs[i] ) { 2849674ae819SStefano Zampini max_local = local_dofs[i]; 2850674ae819SStefano Zampini } 2851674ae819SStefano Zampini } 2852674ae819SStefano Zampini max_local++; 2853674ae819SStefano Zampini /* allocate workspace */ 2854674ae819SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&local_vec);CHKERRQ(ierr); 2855674ae819SStefano Zampini ierr = VecSetSizes(local_vec,PETSC_DECIDE,max_local);CHKERRQ(ierr); 2856674ae819SStefano Zampini ierr = VecSetType(local_vec,VECSEQ);CHKERRQ(ierr); 2857674ae819SStefano Zampini ierr = VecCreate(comm,&global_vec);CHKERRQ(ierr); 2858674ae819SStefano Zampini ierr = VecSetSizes(global_vec,PETSC_DECIDE,max_global);CHKERRQ(ierr); 2859674ae819SStefano Zampini ierr = VecSetType(global_vec,VECMPI);CHKERRQ(ierr); 2860674ae819SStefano Zampini /* create scatter */ 2861674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_local_dofs,local_dofs,PETSC_COPY_VALUES,&seqis);CHKERRQ(ierr); 2862674ae819SStefano Zampini ierr = ISCreateGeneral(comm,n_local_dofs,temp_global_dofs,PETSC_COPY_VALUES,&paris);CHKERRQ(ierr); 2863674ae819SStefano Zampini ierr = VecScatterCreate(local_vec,seqis,global_vec,paris,&scatter_ctx);CHKERRQ(ierr); 2864674ae819SStefano Zampini ierr = ISDestroy(&seqis);CHKERRQ(ierr); 2865674ae819SStefano Zampini ierr = ISDestroy(&paris);CHKERRQ(ierr); 2866674ae819SStefano Zampini /* init array */ 2867674ae819SStefano Zampini ierr = VecSet(global_vec,0.0);CHKERRQ(ierr); 2868674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 2869674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 2870674ae819SStefano Zampini if (local_dofs_mult) { 2871674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2872674ae819SStefano Zampini array[local_dofs[i]]=(PetscScalar)local_dofs_mult[i]; 2873674ae819SStefano Zampini } 2874674ae819SStefano Zampini } else { 2875674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2876674ae819SStefano Zampini array[local_dofs[i]]=1.0; 2877674ae819SStefano Zampini } 2878674ae819SStefano Zampini } 2879674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 2880674ae819SStefano Zampini /* scatter into global vec and get total number of global dofs */ 2881674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2882674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2883674ae819SStefano Zampini ierr = VecSum(global_vec,&globalsum);CHKERRQ(ierr); 28845b08dc53SStefano Zampini *n_global_subset = (PetscInt)PetscRealPart(globalsum); 2885674ae819SStefano Zampini /* Fill global_vec with cumulative function for global numbering */ 2886674ae819SStefano Zampini ierr = VecGetArray(global_vec,&array);CHKERRQ(ierr); 2887674ae819SStefano Zampini ierr = VecGetLocalSize(global_vec,&s);CHKERRQ(ierr); 2888674ae819SStefano Zampini nlocals = 0; 2889674ae819SStefano Zampini first_index = -1; 2890674ae819SStefano Zampini first_found = PETSC_FALSE; 2891674ae819SStefano Zampini for (i=0;i<s;i++) { 2892b9b85e73SStefano Zampini if (!first_found && PetscRealPart(array[i]) > 0.1) { 2893674ae819SStefano Zampini first_found = PETSC_TRUE; 2894674ae819SStefano Zampini first_index = i; 2895674ae819SStefano Zampini } 28965b08dc53SStefano Zampini nlocals += (PetscInt)PetscRealPart(array[i]); 2897674ae819SStefano Zampini } 2898674ae819SStefano Zampini ierr = MPI_Gather(&nlocals,1,MPIU_INT,dof_sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 2899674ae819SStefano Zampini if (!rank_prec_comm) { 2900674ae819SStefano Zampini dof_displs[0]=0; 2901674ae819SStefano Zampini for (i=1;i<size_prec_comm;i++) { 2902674ae819SStefano Zampini dof_displs[i] = dof_displs[i-1]+dof_sizes[i-1]; 2903674ae819SStefano Zampini } 2904674ae819SStefano Zampini } 2905674ae819SStefano Zampini ierr = MPI_Scatter(dof_displs,1,MPIU_INT,&nlocals,1,MPIU_INT,0,comm);CHKERRQ(ierr); 2906674ae819SStefano Zampini if (first_found) { 2907674ae819SStefano Zampini array[first_index] += (PetscScalar)nlocals; 2908674ae819SStefano Zampini old_index = first_index; 2909674ae819SStefano Zampini for (i=first_index+1;i<s;i++) { 2910b9b85e73SStefano Zampini if (PetscRealPart(array[i]) > 0.1) { 2911674ae819SStefano Zampini array[i] += array[old_index]; 2912674ae819SStefano Zampini old_index = i; 2913674ae819SStefano Zampini } 2914674ae819SStefano Zampini } 2915674ae819SStefano Zampini } 2916674ae819SStefano Zampini ierr = VecRestoreArray(global_vec,&array);CHKERRQ(ierr); 2917674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 2918674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2919674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2920674ae819SStefano Zampini /* get global ordering of local dofs */ 2921674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 2922674ae819SStefano Zampini if (local_dofs_mult) { 2923674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 29245b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-local_dofs_mult[i]; 2925674ae819SStefano Zampini } 2926674ae819SStefano Zampini } else { 2927674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 29285b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-1; 2929674ae819SStefano Zampini } 2930674ae819SStefano Zampini } 2931674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 2932674ae819SStefano Zampini /* free workspace */ 2933674ae819SStefano Zampini ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); 2934674ae819SStefano Zampini ierr = VecDestroy(&local_vec);CHKERRQ(ierr); 2935674ae819SStefano Zampini ierr = VecDestroy(&global_vec);CHKERRQ(ierr); 2936674ae819SStefano Zampini ierr = PetscFree(dof_sizes);CHKERRQ(ierr); 2937674ae819SStefano Zampini ierr = PetscFree(dof_displs);CHKERRQ(ierr); 2938674ae819SStefano Zampini /* return pointer to global ordering of local dofs */ 2939674ae819SStefano Zampini *global_numbering_subset = temp_global_dofs; 2940674ae819SStefano Zampini PetscFunctionReturn(0); 2941674ae819SStefano Zampini } 29429a7d3425SStefano Zampini 29439a7d3425SStefano Zampini #undef __FUNCT__ 29449a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 29459a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 29469a7d3425SStefano Zampini { 29479a7d3425SStefano Zampini PetscInt i,j; 29489a7d3425SStefano Zampini PetscScalar *alphas; 29499a7d3425SStefano Zampini PetscErrorCode ierr; 29509a7d3425SStefano Zampini 29519a7d3425SStefano Zampini PetscFunctionBegin; 29529a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 2953785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 29549a7d3425SStefano Zampini for (i=0;i<n;i++) { 29559a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 29569a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 29579a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 29589a7d3425SStefano Zampini } 29599a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 29609a7d3425SStefano Zampini PetscFunctionReturn(0); 29619a7d3425SStefano Zampini } 29629a7d3425SStefano Zampini 2963e7931f94SStefano Zampini #undef __FUNCT__ 296470cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 296528143c3dSStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscBool contiguous, IS* is_sends) 2966e7931f94SStefano Zampini { 2967e7931f94SStefano Zampini Mat subdomain_adj; 2968e7931f94SStefano Zampini IS new_ranks,ranks_send_to; 2969e7931f94SStefano Zampini MatPartitioning partitioner; 2970e7931f94SStefano Zampini Mat_IS *matis; 2971e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 2972e7931f94SStefano Zampini PetscInt prank; 2973e7931f94SStefano Zampini PetscMPIInt size,rank,color; 2974e7931f94SStefano Zampini PetscInt *xadj,*adjncy,*oldranks; 2975e7931f94SStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*is_indices,*ranks_send_to_idx; 29763837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 2977e7931f94SStefano Zampini PetscErrorCode ierr; 29782b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 2979e7931f94SStefano Zampini PetscSubcomm subcomm; 2980a57a6d2fSStefano Zampini 2981e7931f94SStefano Zampini PetscFunctionBegin; 29822b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 29832b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 29842b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 2985e7931f94SStefano Zampini 2986e7931f94SStefano Zampini /* Get info on mapping */ 2987e7931f94SStefano Zampini matis = (Mat_IS*)(mat->data); 2988e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&local_size);CHKERRQ(ierr); 2989e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 2990e7931f94SStefano Zampini 2991e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 2992785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 2993e7931f94SStefano Zampini xadj[0] = 0; 2994e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 2995785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 2996785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 2997e7931f94SStefano Zampini 29982b510759SStefano Zampini if (threshold) { 2999d023bfaeSStefano Zampini PetscInt xadj_count = 0; 30002b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 3001d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 3002d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 3003d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 3004d023bfaeSStefano Zampini xadj_count++; 3005e7931f94SStefano Zampini } 3006e7931f94SStefano Zampini } 3007d023bfaeSStefano Zampini xadj[1] = xadj_count; 3008c8587f34SStefano Zampini } else { 3009e7931f94SStefano Zampini if (xadj[1]) { 3010e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 3011e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 3012c8587f34SStefano Zampini } 3013e7931f94SStefano Zampini } 3014e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3015e7931f94SStefano Zampini if (use_square) { 3016e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3017e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3018e7931f94SStefano Zampini } 3019e7931f94SStefano Zampini } 3020e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3021e7931f94SStefano Zampini 30223837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3023e7931f94SStefano Zampini 3024e7931f94SStefano Zampini /* 3025e7931f94SStefano Zampini Restrict work on active processes only. 3026e7931f94SStefano Zampini */ 3027e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3028e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3029e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 30302b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3031d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3032e7931f94SStefano Zampini if (color) { 3033e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3034e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3035e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3036c8587f34SStefano Zampini } else { 303728143c3dSStefano Zampini PetscInt coarsening_ratio; 3038e7931f94SStefano Zampini ierr = MPI_Comm_size(subcomm->comm,&size);CHKERRQ(ierr); 3039785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3040e7931f94SStefano Zampini prank = rank; 3041e7931f94SStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm->comm);CHKERRQ(ierr); 30428002ef2cSStefano Zampini /* 3043e7931f94SStefano Zampini for (i=0;i<size;i++) { 3044e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3045c8587f34SStefano Zampini } 30468002ef2cSStefano Zampini */ 3047e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3048e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3049c8587f34SStefano Zampini } 3050e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3051e7931f94SStefano Zampini ierr = MatCreateMPIAdj(subcomm->comm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 305222b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3053e7931f94SStefano Zampini 3054e7931f94SStefano Zampini /* Partition */ 3055e7931f94SStefano Zampini ierr = MatPartitioningCreate(subcomm->comm,&partitioner);CHKERRQ(ierr); 3056e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3057e7931f94SStefano Zampini if (use_vwgt) { 30583837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3059e7931f94SStefano Zampini v_wgt[0] = local_size; 3060e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3061c8587f34SStefano Zampini } 306228143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 306328143c3dSStefano Zampini coarsening_ratio = size/n_subdomains; 306428143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3065e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3066e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 306722b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3068e7931f94SStefano Zampini 3069e7931f94SStefano Zampini ierr = ISGetIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 307028143c3dSStefano Zampini if (contiguous) { 307128143c3dSStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; /* contiguos set of processes */ 307228143c3dSStefano Zampini } else { 307384ba6060SStefano Zampini ranks_send_to_idx[0] = coarsening_ratio*oldranks[is_indices[0]]; /* scattered set of processes */ 307428143c3dSStefano Zampini } 3075e7931f94SStefano Zampini ierr = ISRestoreIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3076e7931f94SStefano Zampini /* clean up */ 3077e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 3078e7931f94SStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 3079e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3080e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3081e7931f94SStefano Zampini } 3082e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3083e7931f94SStefano Zampini 3084e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3085e7931f94SStefano Zampini i = 1; 3086e7931f94SStefano Zampini if (color) i=0; 3087e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3088e7931f94SStefano Zampini 3089e7931f94SStefano Zampini /* get back IS */ 3090e7931f94SStefano Zampini *is_sends = ranks_send_to; 3091e7931f94SStefano Zampini PetscFunctionReturn(0); 3092e7931f94SStefano Zampini } 3093e7931f94SStefano Zampini 3094e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3095e7931f94SStefano Zampini 3096e7931f94SStefano Zampini #undef __FUNCT__ 3097e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 309828143c3dSStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 3099e7931f94SStefano Zampini { 310070cf5478SStefano Zampini Mat local_mat; 3101e7931f94SStefano Zampini Mat_IS *matis; 3102e7931f94SStefano Zampini IS is_sends_internal; 31039d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 310428143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 31059d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3106e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3107e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3108e7931f94SStefano Zampini const PetscInt* is_indices; 3109e7931f94SStefano Zampini MatType new_local_type; 3110e7931f94SStefano Zampini /* buffers */ 3111e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 311228143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 31139d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3114e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3115e7931f94SStefano Zampini /* MPI */ 311628143c3dSStefano Zampini MPI_Comm comm,comm_n; 311728143c3dSStefano Zampini PetscSubcomm subcomm; 3118e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 311928143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 312028143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 312128143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 312228143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 312328143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3124e7931f94SStefano Zampini PetscErrorCode ierr; 3125e7931f94SStefano Zampini 3126e7931f94SStefano Zampini PetscFunctionBegin; 312728143c3dSStefano Zampini /* TODO: add missing checks */ 312828143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 312928143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 313028143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 313128143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3132e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 313328143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3134e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3135e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3136e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3137e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3138e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 313928143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 314070cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 314170cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 314228143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 314370cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 314470cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 314570cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 314670cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 314770cf5478SStefano Zampini } 3148e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 3149e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 3150e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 3151e7931f94SStefano Zampini if (!is_sends) { 315228143c3dSStefano Zampini PetscBool pcontig = PETSC_TRUE; 315328143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 315428143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,pcontig,&is_sends_internal);CHKERRQ(ierr); 3155c8587f34SStefano Zampini } else { 3156e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 3157e7931f94SStefano Zampini is_sends_internal = is_sends; 3158c8587f34SStefano Zampini } 3159e7931f94SStefano Zampini 3160e7931f94SStefano Zampini /* get pointer of MATIS data */ 3161e7931f94SStefano Zampini matis = (Mat_IS*)mat->data; 3162e7931f94SStefano Zampini 3163e7931f94SStefano Zampini /* get comm */ 3164a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3165e7931f94SStefano Zampini 3166e7931f94SStefano Zampini /* compute number of sends */ 3167e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 3168e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 3169e7931f94SStefano Zampini 3170e7931f94SStefano Zampini /* compute number of receives */ 3171e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 3172785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 3173e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 3174e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3175e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 3176e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 3177e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 3178e7931f94SStefano Zampini 317928143c3dSStefano Zampini /* restrict comm if requested */ 318028143c3dSStefano Zampini subcomm = 0; 318128143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 318228143c3dSStefano Zampini if (restrict_comm) { 318328143c3dSStefano Zampini PetscMPIInt color,rank,subcommsize; 318428143c3dSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 318528143c3dSStefano Zampini color = 0; 318628143c3dSStefano Zampini if (n_sends && !n_recvs) color = 1; /* sending only processes will not partecipate in new comm */ 318728143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 318828143c3dSStefano Zampini subcommsize = commsize - subcommsize; 318928143c3dSStefano Zampini /* check if reuse has been requested */ 319028143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 319128143c3dSStefano Zampini if (*mat_n) { 319228143c3dSStefano Zampini PetscMPIInt subcommsize2; 319328143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 319428143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 319528143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 319628143c3dSStefano Zampini } else { 319728143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 319828143c3dSStefano Zampini } 319928143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 320028143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 320128143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 320228143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 320328143c3dSStefano Zampini comm_n = subcomm->comm; 320428143c3dSStefano Zampini } 320528143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 320628143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 320728143c3dSStefano Zampini } else { 320828143c3dSStefano Zampini comm_n = comm; 320928143c3dSStefano Zampini } 321028143c3dSStefano Zampini 3211e7931f94SStefano Zampini /* prepare send/receive buffers */ 3212785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 3213e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 3214785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 3215e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 321628143c3dSStefano Zampini if (nis) { 3217854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 321828143c3dSStefano Zampini } 3219e7931f94SStefano Zampini 322028143c3dSStefano Zampini /* Get data from local matrices */ 3221e7931f94SStefano Zampini if (!isdense) { 3222a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 3223e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 3224e7931f94SStefano Zampini /* 3225e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 3226e7931f94SStefano Zampini send_buffer_idxs should contain: 3227e7931f94SStefano Zampini - MatType_PRIVATE type 3228e7931f94SStefano Zampini - PetscInt size_of_l2gmap 3229e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 3230e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 3231e7931f94SStefano Zampini */ 3232e7931f94SStefano Zampini } else { 3233e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3234e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&i);CHKERRQ(ierr); 3235854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 3236e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 3237e7931f94SStefano Zampini send_buffer_idxs[1] = i; 3238e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3239e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 3240e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3241e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 3242e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3243e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 3244e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 3245c8587f34SStefano Zampini } 3246c8587f34SStefano Zampini } 3247e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 324828143c3dSStefano Zampini /* additional is (if any) */ 324928143c3dSStefano Zampini if (nis) { 325028143c3dSStefano Zampini PetscMPIInt psum; 325128143c3dSStefano Zampini PetscInt j; 325228143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 325328143c3dSStefano Zampini PetscInt plen; 325428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 325528143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 325628143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 325728143c3dSStefano Zampini } 3258854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 325928143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 326028143c3dSStefano Zampini PetscInt plen; 326128143c3dSStefano Zampini const PetscInt *is_array_idxs; 326228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 326328143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 326428143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 326528143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 326628143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 326728143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 326828143c3dSStefano Zampini } 326928143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 327028143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 327128143c3dSStefano Zampini } 327228143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 327328143c3dSStefano Zampini } 327428143c3dSStefano Zampini 3275e7931f94SStefano Zampini buf_size_idxs = 0; 3276e7931f94SStefano Zampini buf_size_vals = 0; 327728143c3dSStefano Zampini buf_size_idxs_is = 0; 3278e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3279e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 3280e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 328128143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 3282e7931f94SStefano Zampini } 3283785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 3284785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 328595ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 3286e7931f94SStefano Zampini 3287e7931f94SStefano Zampini /* get new tags for clean communications */ 3288e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 3289e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 329028143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 3291e7931f94SStefano Zampini 3292e7931f94SStefano Zampini /* allocate for requests */ 3293785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 3294785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 329595ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 3296785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 3297785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 329895ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 3299e7931f94SStefano Zampini 3300e7931f94SStefano Zampini /* communications */ 3301e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3302e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 330328143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 3304e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3305e7931f94SStefano Zampini source_dest = onodes[i]; 3306e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 3307e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 3308e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3309e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 331028143c3dSStefano Zampini if (nis) { 331128143c3dSStefano 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); 331228143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 331328143c3dSStefano Zampini } 3314e7931f94SStefano Zampini } 3315e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3316e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 3317e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 3318e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 331928143c3dSStefano Zampini if (nis) { 332028143c3dSStefano 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); 332128143c3dSStefano Zampini } 3322e7931f94SStefano Zampini } 3323e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3324e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 3325e7931f94SStefano Zampini 3326e7931f94SStefano Zampini /* assemble new l2g map */ 3327e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3328e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 33299d30be91SStefano Zampini new_local_rows = 0; 3330e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 33319d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3332e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3333e7931f94SStefano Zampini } 33349d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 3335e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 33369d30be91SStefano Zampini new_local_rows = 0; 3337e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 33389d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 33399d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3340e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3341e7931f94SStefano Zampini } 33429d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 33439d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 3344e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 3345e7931f94SStefano Zampini 3346e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 3347e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 3348e7931f94SStefano 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) */ 3349e7931f94SStefano Zampini if (n_recvs) { 335028143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 3351e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3352e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3353e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 3354e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 3355e7931f94SStefano Zampini break; 3356e7931f94SStefano Zampini } 3357e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3358e7931f94SStefano Zampini } 3359e7931f94SStefano Zampini switch (new_local_type_private) { 336028143c3dSStefano Zampini case MATDENSE_PRIVATE: 336128143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 3362e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3363e7931f94SStefano Zampini bs = 1; 336428143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 336528143c3dSStefano Zampini new_local_type = MATSEQDENSE; 336628143c3dSStefano Zampini bs = 1; 336728143c3dSStefano Zampini } 3368e7931f94SStefano Zampini break; 3369e7931f94SStefano Zampini case MATAIJ_PRIVATE: 3370e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3371e7931f94SStefano Zampini bs = 1; 3372e7931f94SStefano Zampini break; 3373e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 3374e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 3375e7931f94SStefano Zampini break; 3376e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 3377e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 3378e7931f94SStefano Zampini break; 3379e7931f94SStefano Zampini default: 33809d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 3381e7931f94SStefano Zampini break; 3382e7931f94SStefano Zampini } 338328143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 338428143c3dSStefano Zampini new_local_type = MATSEQDENSE; 338528143c3dSStefano Zampini bs = 1; 3386e7931f94SStefano Zampini } 3387e7931f94SStefano Zampini 338870cf5478SStefano Zampini /* create MATIS object if needed */ 338970cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 3390e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 339128143c3dSStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,mat_n);CHKERRQ(ierr); 339270cf5478SStefano Zampini } else { 339370cf5478SStefano Zampini /* it also destroys the local matrices */ 339470cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 339570cf5478SStefano Zampini } 339670cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 3397e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 33989d30be91SStefano Zampini 33999d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 34009d30be91SStefano Zampini 34019d30be91SStefano Zampini /* Global to local map of received indices */ 34029d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 34039d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 34049d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 34059d30be91SStefano Zampini 34069d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 34079d30be91SStefano Zampini buf_size_idxs = 0; 34089d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 34099d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 34109d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 34119d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 34129d30be91SStefano Zampini } 34139d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 34149d30be91SStefano Zampini 34159d30be91SStefano Zampini /* set preallocation */ 34169d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 34179d30be91SStefano Zampini if (!newisdense) { 34189d30be91SStefano Zampini PetscInt *new_local_nnz=0; 34199d30be91SStefano Zampini 34209d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 34219d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 34229d30be91SStefano Zampini if (n_recvs) { 34239d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 34249d30be91SStefano Zampini } 34259d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 34269d30be91SStefano Zampini PetscInt j; 34279d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 34289d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 34299d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 34309d30be91SStefano Zampini } 34319d30be91SStefano Zampini } else { 34329d30be91SStefano Zampini /* TODO */ 34339d30be91SStefano Zampini } 34349d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 34359d30be91SStefano Zampini } 34369d30be91SStefano Zampini if (new_local_nnz) { 34379d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 34389d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 34399d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 34409d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 34419d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 34429d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 34439d30be91SStefano Zampini } else { 34449d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 34459d30be91SStefano Zampini } 34469d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 34479d30be91SStefano Zampini } else { 34489d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 34499d30be91SStefano Zampini } 3450e7931f94SStefano Zampini 3451e7931f94SStefano Zampini /* set values */ 3452e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 34539d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 3454e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3455e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 3456e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 34579d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 3458e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3459e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3460e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 346128143c3dSStefano Zampini } else { 346228143c3dSStefano Zampini /* TODO */ 3463e7931f94SStefano Zampini } 3464e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3465e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 3466e7931f94SStefano Zampini } 3467e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3468e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 346970cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 347070cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 34719d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 34729d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 3473e7931f94SStefano Zampini 3474dfd14d43SStefano Zampini #if 0 347528143c3dSStefano Zampini if (!restrict_comm) { /* check */ 3476e7931f94SStefano Zampini Vec lvec,rvec; 3477e7931f94SStefano Zampini PetscReal infty_error; 3478e7931f94SStefano Zampini 34792a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 3480e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 3481e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 3482e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 348370cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 3484e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 3485e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 3486e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 3487e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 3488e7931f94SStefano Zampini } 348928143c3dSStefano Zampini #endif 3490e7931f94SStefano Zampini 349128143c3dSStefano Zampini /* assemble new additional is (if any) */ 349228143c3dSStefano Zampini if (nis) { 349328143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 349428143c3dSStefano Zampini 349528143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3496854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 349728143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 349828143c3dSStefano Zampini psum = 0; 349928143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 350028143c3dSStefano Zampini for (j=0;j<nis;j++) { 350128143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 350228143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 350328143c3dSStefano Zampini psum += plen; 350428143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 350528143c3dSStefano Zampini } 350628143c3dSStefano Zampini } 3507854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 3508854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 350928143c3dSStefano Zampini for (i=1;i<nis;i++) { 351028143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 351128143c3dSStefano Zampini } 351228143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 351328143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 351428143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 351528143c3dSStefano Zampini for (j=0;j<nis;j++) { 351628143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 351728143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 351828143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 351928143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 352028143c3dSStefano Zampini } 352128143c3dSStefano Zampini } 352228143c3dSStefano Zampini for (i=0;i<nis;i++) { 352328143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 352428143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 352528143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 352628143c3dSStefano Zampini } 352728143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 352828143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 352928143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 353028143c3dSStefano Zampini } 3531e7931f94SStefano Zampini /* free workspace */ 353228143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 3533e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3534e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 3535e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3536e7931f94SStefano Zampini if (isdense) { 3537e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3538e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3539e7931f94SStefano Zampini } else { 3540e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 3541e7931f94SStefano Zampini } 354228143c3dSStefano Zampini if (nis) { 354328143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 354428143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 354528143c3dSStefano Zampini } 3546e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 3547e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 354828143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 3549e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 3550e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 355128143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 3552e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 3553e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 3554e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 3555e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 3556e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 355728143c3dSStefano Zampini if (nis) { 355828143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 355928143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 356028143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 356128143c3dSStefano Zampini } 356228143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 356328143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 356428143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 356528143c3dSStefano Zampini for (i=0;i<nis;i++) { 356628143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 356728143c3dSStefano Zampini } 356828143c3dSStefano Zampini } 3569e7931f94SStefano Zampini PetscFunctionReturn(0); 3570e7931f94SStefano Zampini } 3571a57a6d2fSStefano Zampini 357212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 357312edc857SStefano Zampini #include <petsc-private/kspimpl.h> 357412edc857SStefano Zampini 3575c8587f34SStefano Zampini #undef __FUNCT__ 3576c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 3577c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 3578c8587f34SStefano Zampini { 3579c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3580c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 358120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 35829881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 358320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 35846e683305SStefano Zampini IS coarse_is,*isarray; 35856e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 35866e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 3587f9eb5b7dSStefano Zampini PC pc_temp; 3588c8587f34SStefano Zampini PCType coarse_pc_type; 3589c8587f34SStefano Zampini KSPType coarse_ksp_type; 3590f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 35914f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 35926e683305SStefano Zampini Mat t_coarse_mat_is; 35936e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 35946e683305SStefano Zampini PetscMPIInt all_procs; 359574e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 359668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 359722bc73bbSStefano Zampini PetscScalar *array; 35989881197aSStefano Zampini PetscErrorCode ierr; 3599fdc09c96SStefano Zampini 3600c8587f34SStefano Zampini PetscFunctionBegin; 3601c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 360268457ee5SStefano 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 */ 360368457ee5SStefano Zampini compute_vecs = PETSC_TRUE; 3604fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 3605fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 3606f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 3607f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 3608f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 3609fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 3610fa7f1dd8SStefano Zampini if (ocoarse_size != pcbddc->coarse_size) { /* ...but with different size, so reset it and set reuse flag to false */ 3611727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3612fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3613fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 3614fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3615f4ddd8eeSStefano Zampini } 3616fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 3617fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3618f4ddd8eeSStefano Zampini } 361970cf5478SStefano Zampini /* reset any subassembling information */ 362070cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 36216e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 36226e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 3623fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3624f4ddd8eeSStefano Zampini } 3625c8587f34SStefano Zampini 36266e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 36272b510759SStefano Zampini im_active = !!(pcis->n); 36282b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 36296e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 36306e683305SStefano Zampini void_procs = all_procs-active_procs; 36316e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 363274e2c79eSStefano Zampini redist = PETSC_FALSE; 363322bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 36346e683305SStefano Zampini csin_ml = PETSC_TRUE; 36356e683305SStefano Zampini ncoarse_ml = void_procs; 36366e683305SStefano Zampini csin_ds = PETSC_TRUE; 36376e683305SStefano Zampini ncoarse_ds = void_procs; 36386e683305SStefano Zampini } else { 36396e683305SStefano Zampini csin_ml = PETSC_FALSE; 36406e683305SStefano Zampini ncoarse_ml = all_procs; 36416e683305SStefano Zampini if (void_procs) { 36426e683305SStefano Zampini csin_ds = PETSC_TRUE; 36436e683305SStefano Zampini ncoarse_ds = void_procs; 36446e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 36456e683305SStefano Zampini } else { 364674e2c79eSStefano Zampini if (pcbddc->redistribute_coarse && pcbddc->redistribute_coarse < all_procs) { 364774e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 364874e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 364974e2c79eSStefano Zampini redist = PETSC_TRUE; 365074e2c79eSStefano Zampini } else { 36516e683305SStefano Zampini csin_ds = PETSC_FALSE; 36526e683305SStefano Zampini ncoarse_ds = all_procs; 36536e683305SStefano Zampini } 36546e683305SStefano Zampini } 365574e2c79eSStefano Zampini } 36566e683305SStefano Zampini 36576e683305SStefano Zampini /* 36586e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 36596e683305SStefano Zampini - we have not exceeded the number of levels requested 36606e683305SStefano Zampini - we can actually subassemble the active processes 36616e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 36626e683305SStefano Zampini */ 36636e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 36646e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 36656e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 36666e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 36676e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 3668f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 36692b510759SStefano Zampini } else { 3670f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 3671c8587f34SStefano Zampini } 3672c8587f34SStefano Zampini } 36736e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 36746e683305SStefano Zampini if (multilevel_allowed) { 36756e683305SStefano Zampini ncoarse = ncoarse_ml; 36766e683305SStefano Zampini csin = csin_ml; 36776e683305SStefano Zampini } else { 36786e683305SStefano Zampini ncoarse = ncoarse_ds; 36796e683305SStefano Zampini csin = csin_ds; 36806e683305SStefano Zampini } 3681e7931f94SStefano Zampini 3682abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 3683abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 3684abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 3685abbbba34SStefano Zampini 3686abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 368722bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 368822bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 368922bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 369022bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 3691b9b85e73SStefano Zampini #if 0 3692b9b85e73SStefano Zampini { 3693b9b85e73SStefano Zampini PetscViewer viewer; 3694b9b85e73SStefano Zampini char filename[256]; 3695b9b85e73SStefano Zampini sprintf(filename,"local_coarse_mat%d.m",PetscGlobalRank); 3696b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3697b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3698b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 3699b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3700b9b85e73SStefano Zampini } 3701b9b85e73SStefano Zampini #endif 37026e683305SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)pc),1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_islg,&t_coarse_mat_is);CHKERRQ(ierr); 37036e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 37046e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 37056e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3706abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 3707abbbba34SStefano Zampini 37086e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 37096e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 37106e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 37116e683305SStefano Zampini const PetscInt *idxs; 37126e683305SStefano Zampini ISLocalToGlobalMapping tmap; 37136e683305SStefano Zampini 37146e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 37150be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 37166e683305SStefano Zampini /* allocate space for temporary storage */ 3717854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 3718854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 37196e683305SStefano Zampini /* allocate for IS array */ 37206e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 37216e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 37226e683305SStefano Zampini nis = nisdofs + nisneu; 3723854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 37246e683305SStefano Zampini /* dofs splitting */ 37256e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 37266e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 37276e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 37286e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 37296e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 37306e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 37316e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 37326e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 37336e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 37346e683305SStefano Zampini } 37356e683305SStefano Zampini /* neumann boundaries */ 37366e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 37376e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 37386e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 37396e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 37406e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 37416e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 37426e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 37436e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 37446e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 37456e683305SStefano Zampini } 37466e683305SStefano Zampini /* free memory */ 37476e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 37486e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 37496e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 37506e683305SStefano Zampini } else { 37516e683305SStefano Zampini nis = 0; 37526e683305SStefano Zampini nisdofs = 0; 37536e683305SStefano Zampini nisneu = 0; 37546e683305SStefano Zampini isarray = NULL; 37556e683305SStefano Zampini } 37566e683305SStefano Zampini /* destroy no longer needed map */ 37576e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 37586e683305SStefano Zampini 37596e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 37606e683305SStefano Zampini coarse_mat_is = NULL; 37616e683305SStefano Zampini if (csin) { 37626e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 376374e2c79eSStefano Zampini if (redist) { 376474e2c79eSStefano Zampini PetscMPIInt rank; 376574e2c79eSStefano Zampini PetscInt spc,n_spc_p1,dest[1]; 376674e2c79eSStefano Zampini 376774e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 376874e2c79eSStefano Zampini spc = all_procs/pcbddc->redistribute_coarse; 376974e2c79eSStefano Zampini n_spc_p1 = all_procs%pcbddc->redistribute_coarse; 377074e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 377174e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 377274e2c79eSStefano Zampini } else { 377374e2c79eSStefano Zampini dest[0] = rank/(spc+1); 377474e2c79eSStefano Zampini } 377574e2c79eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),1,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 377674e2c79eSStefano Zampini } else { 37776e683305SStefano Zampini PetscInt j,tissize,*nisindices; 37786e683305SStefano Zampini PetscInt *coarse_candidates; 37796e683305SStefano Zampini const PetscInt* tisindices; 37806e683305SStefano Zampini /* get coarse candidates' ranks in pc communicator */ 3781854ce69bSBarry Smith ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 37826e683305SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 37836e683305SStefano Zampini for (i=0,j=0;i<all_procs;i++) { 37846e683305SStefano Zampini if (!coarse_candidates[i]) { 37856e683305SStefano Zampini coarse_candidates[j]=i; 37866e683305SStefano Zampini j++; 37876e683305SStefano Zampini } 37886e683305SStefano Zampini } 37896e683305SStefano Zampini if (j < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",j,ncoarse); 37906e683305SStefano Zampini /* get a suitable subassembling pattern */ 37916e683305SStefano Zampini if (csin_type_simple) { 37926e683305SStefano Zampini PetscMPIInt rank; 37936e683305SStefano Zampini PetscInt issize,isidx; 37946e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 37956e683305SStefano Zampini if (im_active) { 37966e683305SStefano Zampini issize = 1; 37976e683305SStefano Zampini isidx = (PetscInt)rank; 37986e683305SStefano Zampini } else { 37996e683305SStefano Zampini issize = 0; 38006e683305SStefano Zampini isidx = -1; 38016e683305SStefano Zampini } 38026e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 38036e683305SStefano Zampini } else { 38046e683305SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,PETSC_TRUE,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 38056e683305SStefano Zampini } 38066e683305SStefano Zampini if (pcbddc->dbg_flag) { 38076e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 38086e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 38096e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 38106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 38116e683305SStefano Zampini for (i=0;i<j;i++) { 38126e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 38136e683305SStefano Zampini } 38146e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 38156e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38166e683305SStefano Zampini } 38176e683305SStefano Zampini /* shift the pattern on coarse candidates */ 38186e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 38196e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 3820854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 38216e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 38226e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 38236e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 38246e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 38256e683305SStefano Zampini } 382674e2c79eSStefano Zampini } 38276e683305SStefano Zampini if (pcbddc->dbg_flag) { 38286e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 38296e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 38306e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 38316e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38326e683305SStefano Zampini } 38336e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 38346e683305SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 38356e683305SStefano Zampini } else { 38366e683305SStefano Zampini if (pcbddc->dbg_flag) { 38376e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 38386e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 38396e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38406e683305SStefano Zampini } 38416e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 38426e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 38436e683305SStefano Zampini } 38446e683305SStefano Zampini 38456e683305SStefano Zampini /* create local to global scatters for coarse problem */ 384668457ee5SStefano Zampini if (compute_vecs) { 38476e683305SStefano Zampini PetscInt lrows; 38486e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 38496e683305SStefano Zampini if (coarse_mat_is) { 38506e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 38516e683305SStefano Zampini } else { 38526e683305SStefano Zampini lrows = 0; 38536e683305SStefano Zampini } 38546e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 38556e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 38566e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 38576e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 38586e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 38596e683305SStefano Zampini } 38606e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 38616e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 3862c8587f34SStefano Zampini 3863f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 3864f9eb5b7dSStefano Zampini if (multilevel_allowed) { 3865f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 3866f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 3867f9eb5b7dSStefano Zampini } else { 3868f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 3869f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 3870c8587f34SStefano Zampini } 3871c8587f34SStefano Zampini 38726e683305SStefano Zampini /* print some info if requested */ 38736e683305SStefano Zampini if (pcbddc->dbg_flag) { 38746e683305SStefano Zampini if (!multilevel_allowed) { 38756e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 38766e683305SStefano Zampini if (multilevel_requested) { 38776e683305SStefano 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); 38786e683305SStefano Zampini } else if (pcbddc->max_levels) { 38796e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 38806e683305SStefano Zampini } 38816e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38826e683305SStefano Zampini } 38836e683305SStefano Zampini } 38846e683305SStefano Zampini 3885f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 38866e683305SStefano Zampini if (coarse_mat_is) { 38876e683305SStefano Zampini MatReuse coarse_mat_reuse; 38886a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 38896e683305SStefano Zampini if (pcbddc->dbg_flag) { 38906e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 38916e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 38926e683305SStefano Zampini } 3893f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 3894312be037SStefano Zampini char prefix[256],str_level[16]; 3895e604994aSStefano Zampini size_t len; 38966e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 3897c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 3898f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 38995f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 3900c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 39016e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 3902c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 3903c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 3904e604994aSStefano Zampini /* prefix */ 3905e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 3906e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 3907e604994aSStefano Zampini if (!pcbddc->current_level) { 3908e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3909e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 3910c8587f34SStefano Zampini } else { 3911e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 3912312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 3913312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 391434d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 3915312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 3916e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 3917e604994aSStefano Zampini } 3918e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 3919f9eb5b7dSStefano Zampini /* allow user customization */ 3920f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 39217e0def11SStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3922312be037SStefano Zampini } 3923f9eb5b7dSStefano Zampini 3924f9eb5b7dSStefano Zampini /* get some info after set from options */ 3925f9eb5b7dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 3926f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 3927f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 39284f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 39296e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 3930f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 3931f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 3932f9eb5b7dSStefano Zampini } 39334f3a063dSStefano Zampini if (isredundant) { 39344f3a063dSStefano Zampini KSP inner_ksp; 39354f3a063dSStefano Zampini PC inner_pc; 39364f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 39374f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 39384f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 39394f3a063dSStefano Zampini } 3940f9eb5b7dSStefano Zampini 39416e683305SStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 3942f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 3943f9eb5b7dSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 3944f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 39456e683305SStefano Zampini if (nisdofs) { 39466e683305SStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 39476e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 39486e683305SStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 39491035eff8SStefano Zampini } 39501035eff8SStefano Zampini } 39516e683305SStefano Zampini if (nisneu) { 39526e683305SStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 39536e683305SStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 39541035eff8SStefano Zampini } 3955fdc09c96SStefano Zampini 3956f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 3957fa7f1dd8SStefano Zampini if (coarse_reuse) { 395881d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 3959fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 39606e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 3961fa7f1dd8SStefano Zampini } else { 39626e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 3963fa7f1dd8SStefano Zampini } 3964c8587f34SStefano Zampini if (isbddc || isnn) { 396522bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 396670cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 396728143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,PETSC_TRUE,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 396822b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 39696e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 39706e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 39716e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 39726e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 397322b6e8a2SStefano Zampini } 397470cf5478SStefano Zampini } 39756e683305SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 397670cf5478SStefano Zampini } else { 397722bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 397822bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 397922bc73bbSStefano Zampini } 398022bc73bbSStefano Zampini } else { 39812e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 3982c8587f34SStefano Zampini } 3983c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 3984c8587f34SStefano Zampini 3985c8587f34SStefano Zampini /* propagate symmetry info to coarse matrix */ 3986b9d89cd5SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 39875a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 3988c8587f34SStefano Zampini 39896e683305SStefano Zampini /* set operators */ 39905f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 39916e683305SStefano Zampini if (pcbddc->dbg_flag) { 39926e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 39936e683305SStefano Zampini } 39946e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 39956e683305SStefano Zampini coarse_mat = 0; 39966e683305SStefano Zampini } 39976e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 3998b9b85e73SStefano Zampini #if 0 3999b9b85e73SStefano Zampini { 4000b9b85e73SStefano Zampini PetscViewer viewer; 4001b9b85e73SStefano Zampini char filename[256]; 4002b9b85e73SStefano Zampini sprintf(filename,"coarse_mat.m"); 4003b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,filename,&viewer);CHKERRQ(ierr); 4004b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4005b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 4006b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4007b9b85e73SStefano Zampini } 4008b9b85e73SStefano Zampini #endif 4009c8587f34SStefano Zampini 4010c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 4011c8587f34SStefano Zampini if (pcbddc->NullSpace) { 4012c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 401398a51de6SStefano Zampini } 401498a51de6SStefano Zampini 401598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 401698a51de6SStefano Zampini Vec crhs,csol; 401798a51de6SStefano Zampini PetscBool ispreonly; 401898a51de6SStefano Zampini if (CoarseNullSpace) { 4019c8587f34SStefano Zampini if (isbddc) { 4020c8587f34SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4021c8587f34SStefano Zampini } else { 4022c8587f34SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 4023c8587f34SStefano Zampini } 4024c8587f34SStefano Zampini } 4025f9eb5b7dSStefano Zampini /* setup coarse ksp */ 4026f9eb5b7dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4027f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4028f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 40296e683305SStefano Zampini /* hack */ 4030f347579bSStefano Zampini if (!csol) { 40312a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4032f9eb5b7dSStefano Zampini } 4033f347579bSStefano Zampini if (!crhs) { 40342a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4035f347579bSStefano Zampini } 4036cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4037cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 40386e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4039c8587f34SStefano Zampini KSP check_ksp; 40402b510759SStefano Zampini KSPType check_ksp_type; 4041c8587f34SStefano Zampini PC check_pc; 40426e683305SStefano Zampini Vec check_vec,coarse_vec; 40436a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 40442b510759SStefano Zampini PetscInt its; 40456e683305SStefano Zampini PetscBool compute_eigs; 40466e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 40476e683305SStefano Zampini PetscInt neigs; 40488e185a42SStefano Zampini const char *prefix; 4049c8587f34SStefano Zampini 40502b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 40516e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 405223ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4053f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 40542b510759SStefano Zampini if (ispreonly) { 40552b510759SStefano Zampini check_ksp_type = KSPPREONLY; 40566e683305SStefano Zampini compute_eigs = PETSC_FALSE; 40572b510759SStefano Zampini } else { 4058cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 40596e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4060c8587f34SStefano Zampini } 4061c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 40626e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 40636e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 40646e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 4065a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 4066a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 4067a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 4068a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 4069c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4070c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4071c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4072c8587f34SStefano Zampini /* create random vec */ 40736e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 40746e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 4075c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 4076c8587f34SStefano Zampini if (CoarseNullSpace) { 4077c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 4078c8587f34SStefano Zampini } 40796e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 4080c8587f34SStefano Zampini /* solve coarse problem */ 40816e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 4082c8587f34SStefano Zampini if (CoarseNullSpace) { 40836e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 4084c8587f34SStefano Zampini } 4085cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 40866e683305SStefano Zampini if (compute_eigs) { 4087854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 4088854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 40896e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 40906e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 40916e683305SStefano Zampini lambda_min = eigs_r[0]; 40926e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 40936e683305SStefano Zampini if (lambda_max>lambda_min) { 4094cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 4095cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 4096cbcc2c2aSStefano Zampini } 4097c8587f34SStefano Zampini } 4098c8587f34SStefano Zampini } 4099cbcc2c2aSStefano Zampini 4100c8587f34SStefano Zampini /* check coarse problem residual error */ 41016e683305SStefano Zampini if (pcbddc->dbg_flag) { 41026e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 41036e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 41046e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 4105c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 41066e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 41076e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 4108c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 41096e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (%d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 41106e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 41116e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 41126e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 41136e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 41146e683305SStefano Zampini if (compute_eigs) { 41156e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 4116deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 4117c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 41186e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 41196e683305SStefano 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); 41206e683305SStefano Zampini for (i=0;i<neigs;i++) { 41216e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 4122c8587f34SStefano Zampini } 41236e683305SStefano Zampini } 41246e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 41256e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 41266e683305SStefano Zampini } 4127c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 41286e683305SStefano Zampini if (compute_eigs) { 41296e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 41306e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 4131c8587f34SStefano Zampini } 41326e683305SStefano Zampini } 41336e683305SStefano Zampini } 4134cbcc2c2aSStefano Zampini /* print additional info */ 4135cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 41366e683305SStefano Zampini /* waits until all processes reaches this point */ 41376e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 4138cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 4139cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4140cbcc2c2aSStefano Zampini } 4141cbcc2c2aSStefano Zampini 41422b510759SStefano Zampini /* free memory */ 4143c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4144fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 4145c8587f34SStefano Zampini PetscFunctionReturn(0); 4146c8587f34SStefano Zampini } 4147674ae819SStefano Zampini 4148f34684f1SStefano Zampini #undef __FUNCT__ 4149f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 4150f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 4151f34684f1SStefano Zampini { 4152f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4153f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 4154f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4155727cdba6SStefano Zampini PetscInt i,coarse_size; 4156727cdba6SStefano Zampini PetscInt *local_primal_indices; 4157f34684f1SStefano Zampini PetscErrorCode ierr; 4158f34684f1SStefano Zampini 4159f34684f1SStefano Zampini PetscFunctionBegin; 4160f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 416189c96988SStefano Zampini if (!pcbddc->primal_indices_local_idxs && pcbddc->local_primal_size) { 416289c96988SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Local primal indices have not been created"); 4163727cdba6SStefano Zampini } 4164727cdba6SStefano Zampini ierr = PCBDDCSubsetNumbering(PetscObjectComm((PetscObject)(pc->pmat)),matis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,NULL,&coarse_size,&local_primal_indices);CHKERRQ(ierr); 4165f34684f1SStefano Zampini 4166f34684f1SStefano Zampini /* check numbering */ 4167f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 4168f34684f1SStefano Zampini PetscScalar coarsesum,*array; 4169b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 4170f34684f1SStefano Zampini 4171f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4172f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4173f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 41740fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 4175f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 4176f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4177727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4178f34684f1SStefano Zampini } 4179f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4180f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4181f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4182f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4183f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4184f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4185f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4186f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4187f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4188f34684f1SStefano Zampini if (array[i] == 1.0) { 4189b9b85e73SStefano Zampini set_error = PETSC_TRUE; 4190f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a single process!\n",PetscGlobalRank,i);CHKERRQ(ierr); 4191f34684f1SStefano Zampini } 4192f34684f1SStefano Zampini } 4193b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4194f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4195f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4196f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 4197f34684f1SStefano Zampini } 4198f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4199f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4200f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4201f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4202f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 4203f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 4204b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 4205f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 4206f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4207f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4208f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4209727cdba6SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i]); 4210f34684f1SStefano Zampini } 4211f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4212f34684f1SStefano Zampini } 4213f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4214b9b85e73SStefano Zampini if (set_error_reduced) { 4215b9b85e73SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 4216b9b85e73SStefano Zampini } 4217f34684f1SStefano Zampini } 4218f34684f1SStefano Zampini /* get back data */ 4219f34684f1SStefano Zampini *coarse_size_n = coarse_size; 4220f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 4221674ae819SStefano Zampini PetscFunctionReturn(0); 4222674ae819SStefano Zampini } 4223674ae819SStefano Zampini 4224e456f2a8SStefano Zampini #undef __FUNCT__ 4225e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 4226a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 4227e456f2a8SStefano Zampini { 4228e456f2a8SStefano Zampini IS localis_t; 4229a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 4230e456f2a8SStefano Zampini PetscScalar *vals; 4231e456f2a8SStefano Zampini PetscErrorCode ierr; 4232e456f2a8SStefano Zampini 4233e456f2a8SStefano Zampini PetscFunctionBegin; 4234a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 4235e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 4236854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 4237e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 4238e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4239a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 4240a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 42411035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 4242a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 42431035eff8SStefano Zampini } 4244a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 4245e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4246e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4247a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 4248a7dc3881SStefano Zampini /* now compute set in local ordering */ 4249a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4250a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4251a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4252a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 4253a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4254ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4255e456f2a8SStefano Zampini lsize++; 4256e456f2a8SStefano Zampini } 4257e456f2a8SStefano Zampini } 4258854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 4259a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4260ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4261e456f2a8SStefano Zampini idxs[lsize++] = i; 4262e456f2a8SStefano Zampini } 4263e456f2a8SStefano Zampini } 4264a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4265a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 4266e456f2a8SStefano Zampini *localis = localis_t; 4267e456f2a8SStefano Zampini PetscFunctionReturn(0); 4268e456f2a8SStefano Zampini } 4269906d46d4SStefano Zampini 4270906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 4271906d46d4SStefano Zampini #undef __FUNCT__ 4272906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 4273906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 4274906d46d4SStefano Zampini { 4275906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4276906d46d4SStefano Zampini PetscErrorCode ierr; 4277906d46d4SStefano Zampini 4278906d46d4SStefano Zampini PetscFunctionBegin; 4279906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4280906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4281906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4282906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4283906d46d4SStefano Zampini PetscFunctionReturn(0); 4284906d46d4SStefano Zampini } 4285906d46d4SStefano Zampini 4286906d46d4SStefano Zampini #undef __FUNCT__ 4287906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 4288906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 4289906d46d4SStefano Zampini { 4290906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4291906d46d4SStefano Zampini PetscErrorCode ierr; 4292906d46d4SStefano Zampini 4293906d46d4SStefano Zampini PetscFunctionBegin; 4294906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4295906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4296906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4297906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4298906d46d4SStefano Zampini PetscFunctionReturn(0); 4299906d46d4SStefano Zampini } 4300b96c3477SStefano Zampini 4301b96c3477SStefano Zampini #undef __FUNCT__ 4302b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 4303*b7eb3628SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc, PetscInt layers, PetscBool use_useradj, PetscBool compute_Stilda) 4304b96c3477SStefano Zampini { 4305b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4306b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4307b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 4308b96c3477SStefano Zampini PetscBool free_used_adj; 4309b96c3477SStefano Zampini PetscErrorCode ierr; 4310b96c3477SStefano Zampini 4311b96c3477SStefano Zampini PetscFunctionBegin; 4312b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 4313b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 4314b96c3477SStefano Zampini if (layers == -1) { 4315b96c3477SStefano Zampini used_xadj = NULL; 4316b96c3477SStefano Zampini used_adjncy = NULL; 4317b96c3477SStefano Zampini } else { 4318b96c3477SStefano Zampini if ( (use_useradj && pcbddc->mat_graph->xadj) || pcbddc->computed_rowadj) { 4319b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 4320b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 4321b96c3477SStefano Zampini } else { 4322b96c3477SStefano Zampini Mat mat_adj; 4323b96c3477SStefano Zampini PetscBool flg_row=PETSC_TRUE; 4324b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 4325b96c3477SStefano Zampini PetscInt nvtxs; 4326b96c3477SStefano Zampini 4327b96c3477SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 4328b96c3477SStefano Zampini ierr = MatGetRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4329b96c3477SStefano Zampini if (!flg_row) { 4330b96c3477SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 4331b96c3477SStefano Zampini } 4332b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 4333b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 4334b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 4335b96c3477SStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4336b96c3477SStefano Zampini if (!flg_row) { 4337b96c3477SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 4338b96c3477SStefano Zampini } 4339b96c3477SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 4340b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 4341b96c3477SStefano Zampini } 4342b96c3477SStefano Zampini } 4343*b7eb3628SStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,used_xadj,used_adjncy,layers,compute_Stilda);CHKERRQ(ierr); 4344b96c3477SStefano Zampini 4345b96c3477SStefano Zampini /* free adjacency */ 4346b96c3477SStefano Zampini if (free_used_adj) { 4347b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 4348b96c3477SStefano Zampini } 4349b96c3477SStefano Zampini PetscFunctionReturn(0); 4350b96c3477SStefano Zampini } 4351b96c3477SStefano Zampini 4352b96c3477SStefano Zampini #undef __FUNCT__ 4353b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 4354b96c3477SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc, PetscBool rebuild, PetscInt threshold) 4355b96c3477SStefano Zampini { 4356b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 4357b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4358b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4359b96c3477SStefano Zampini PCBDDCGraph graph; 4360b96c3477SStefano Zampini Mat S_j; 4361b96c3477SStefano Zampini PetscErrorCode ierr; 4362b96c3477SStefano Zampini 4363b96c3477SStefano Zampini PetscFunctionBegin; 4364b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 4365b96c3477SStefano Zampini if (rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 4366b96c3477SStefano Zampini IS verticesIS; 4367b96c3477SStefano Zampini 4368b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 4369b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 4370b96c3477SStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap);CHKERRQ(ierr); 4371b96c3477SStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticesIS);CHKERRQ(ierr); 4372b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 4373b96c3477SStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 4374b96c3477SStefano Zampini /* 4375b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 4376b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4377b96c3477SStefano Zampini } 4378b96c3477SStefano Zampini */ 4379b96c3477SStefano Zampini } else { 4380b96c3477SStefano Zampini graph = pcbddc->mat_graph; 4381b96c3477SStefano Zampini } 4382b96c3477SStefano Zampini 4383b96c3477SStefano Zampini /* Create Schur complement matrix */ 4384b96c3477SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 4385b96c3477SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 4386b96c3477SStefano Zampini 4387b96c3477SStefano Zampini /* sub_schurs init */ 4388b96c3477SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcbddc->local_mat,S_j,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,threshold);CHKERRQ(ierr); 4389b96c3477SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 4390b96c3477SStefano Zampini /* free graph struct */ 4391b96c3477SStefano Zampini if (rebuild) { 4392b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 4393b96c3477SStefano Zampini } 4394b96c3477SStefano Zampini PetscFunctionReturn(0); 4395b96c3477SStefano Zampini } 4396