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); 92b1b3d7a2SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs[0]);CHKERRQ(ierr); 93b1b3d7a2SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs[1]);CHKERRQ(ierr); 94674ae819SStefano Zampini PetscFunctionReturn(0); 95674ae819SStefano Zampini } 96674ae819SStefano Zampini 97674ae819SStefano Zampini #undef __FUNCT__ 98674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 99674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 100674ae819SStefano Zampini { 101674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 102674ae819SStefano Zampini PetscErrorCode ierr; 103674ae819SStefano Zampini 104674ae819SStefano Zampini PetscFunctionBegin; 105674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 106674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 107674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 108674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 10915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 11015aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 111674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 112674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 113674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 114674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 115674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 116674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 1178ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 118674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 119674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 120674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 121f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 122f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 123f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 124f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 125727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 126f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 12770cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 1286e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 129674ae819SStefano Zampini PetscFunctionReturn(0); 130674ae819SStefano Zampini } 131674ae819SStefano Zampini 132674ae819SStefano Zampini #undef __FUNCT__ 133f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 134f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 1356bfb1811SStefano Zampini { 1366bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1376bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1386bfb1811SStefano Zampini VecType impVecType; 139e9189074SStefano Zampini PetscInt n_constraints,n_R,old_size; 1406bfb1811SStefano Zampini PetscErrorCode ierr; 1416bfb1811SStefano Zampini 1426bfb1811SStefano Zampini PetscFunctionBegin; 143f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 144f4ddd8eeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 145f4ddd8eeSStefano Zampini } 146e7b262bdSStefano Zampini /* get sizes */ 147e9189074SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->n_actual_vertices; 148e9189074SStefano Zampini n_R = pcis->n-pcbddc->n_actual_vertices; 1496bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 150e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 151e7b262bdSStefano Zampini /* R nodes */ 152e7b262bdSStefano Zampini old_size = -1; 153e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 154e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 155e7b262bdSStefano Zampini } 156e7b262bdSStefano Zampini if (n_R != old_size) { 157e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 158e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 1596bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 1606bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 1616bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1626bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 163e7b262bdSStefano Zampini } 164e7b262bdSStefano Zampini /* local primal dofs */ 165e7b262bdSStefano Zampini old_size = -1; 166e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 167e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 168e7b262bdSStefano Zampini } 169e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 170e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 17183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 172e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 1736bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 174e7b262bdSStefano Zampini } 175e7b262bdSStefano Zampini /* local explicit constraints */ 176e7b262bdSStefano Zampini old_size = -1; 177e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 178e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 179e7b262bdSStefano Zampini } 180e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 181e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 18283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 18383b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 18483b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 18583b7ccabSStefano Zampini } 1866bfb1811SStefano Zampini PetscFunctionReturn(0); 1876bfb1811SStefano Zampini } 1886bfb1811SStefano Zampini 1896bfb1811SStefano Zampini #undef __FUNCT__ 19047f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 19147f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 19288ebb749SStefano Zampini { 19325084f0cSStefano Zampini PetscErrorCode ierr; 19425084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 19588ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 19688ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 19725084f0cSStefano Zampini /* submatrices of local problem */ 19888ebb749SStefano Zampini Mat A_RV,A_VR,A_VV; 19925084f0cSStefano Zampini /* working matrices */ 20025084f0cSStefano Zampini Mat M1,M2,M3,C_CR; 20125084f0cSStefano Zampini /* working vectors */ 20225084f0cSStefano Zampini Vec vec1_C,vec2_C,vec1_V,vec2_V; 20325084f0cSStefano Zampini /* additional working stuff */ 20425084f0cSStefano Zampini IS is_aux; 20525084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 20625084f0cSStefano Zampini const PetscScalar *array,*row_cmat_values; 20725084f0cSStefano Zampini const PetscInt *row_cmat_indices,*idx_R_local; 208e9189074SStefano Zampini PetscInt *idx_V_B,*auxindices; 20925084f0cSStefano Zampini PetscInt n_vertices,n_constraints,size_of_constraint; 21025084f0cSStefano Zampini PetscInt i,j,n_R,n_D,n_B; 211b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 21245a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 21388ebb749SStefano Zampini MatType impMatType; 21425084f0cSStefano Zampini /* some shortcuts to scalars */ 21525084f0cSStefano Zampini PetscScalar zero=0.0,one=1.0,m_one=-1.0; 21625084f0cSStefano Zampini /* for debugging purposes */ 21788ebb749SStefano Zampini PetscReal *coarsefunctions_errors,*constraints_errors; 21888ebb749SStefano Zampini 21988ebb749SStefano Zampini PetscFunctionBegin; 220e9189074SStefano Zampini /* get number of vertices (corners plus constraints with change of basis) 221e9189074SStefano Zampini pcbddc->n_actual_vertices stores the actual number of vertices, pcbddc->n_vertices the number of corners computed */ 222e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 22388ebb749SStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 22488ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 22588ebb749SStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 22688ebb749SStefano Zampini n_R = pcis->n-n_vertices; 22788ebb749SStefano Zampini 22888ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 22988ebb749SStefano Zampini impMatType = MATSEQDENSE; 23088ebb749SStefano Zampini 23188ebb749SStefano Zampini /* Allocating some extra storage just to be safe */ 23288ebb749SStefano Zampini ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 23388ebb749SStefano Zampini for (i=0;i<pcis->n;i++) auxindices[i]=i; 23488ebb749SStefano Zampini 23588ebb749SStefano Zampini /* vertices in boundary numbering */ 236785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 2375e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->primal_indices_local_idxs,&i,idx_V_B);CHKERRQ(ierr); 23888ebb749SStefano Zampini if (i != n_vertices) { 23922d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 24088ebb749SStefano Zampini } 24188ebb749SStefano Zampini 24288ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 24388ebb749SStefano Zampini if (n_constraints) { 244f4ddd8eeSStefano Zampini /* see if we can save some allocations */ 245f4ddd8eeSStefano Zampini if (pcbddc->local_auxmat2) { 246f4ddd8eeSStefano Zampini PetscInt on_R,on_constraints; 247f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->local_auxmat2,&on_R,&on_constraints);CHKERRQ(ierr); 248f4ddd8eeSStefano Zampini if (on_R != n_R || on_constraints != n_constraints) { 249f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 250f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 251f4ddd8eeSStefano Zampini } 252f4ddd8eeSStefano Zampini } 25345a1bb75SStefano Zampini /* work vectors */ 25445a1bb75SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_C,&vec1_C);CHKERRQ(ierr); 25545a1bb75SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_C,&vec2_C);CHKERRQ(ierr); 25645a1bb75SStefano Zampini /* auxiliary matrices */ 257f4ddd8eeSStefano Zampini if (!pcbddc->local_auxmat2) { 25888ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 25925084f0cSStefano Zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 26088ebb749SStefano Zampini ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 26125084f0cSStefano Zampini ierr = MatSetUp(pcbddc->local_auxmat2);CHKERRQ(ierr); 262f4ddd8eeSStefano Zampini } 26388ebb749SStefano Zampini 26425084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 26525084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 2668ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 26725084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 26888ebb749SStefano Zampini 26988ebb749SStefano Zampini /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 27088ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 27188ebb749SStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 27288ebb749SStefano Zampini /* Get row of constraint matrix in R numbering */ 27325084f0cSStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 27425084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_R,size_of_constraint,row_cmat_indices,row_cmat_values,INSERT_VALUES);CHKERRQ(ierr); 27525084f0cSStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 27625084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_R);CHKERRQ(ierr); 27725084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_R);CHKERRQ(ierr); 27888ebb749SStefano Zampini /* Solve for row of constraint matrix in R numbering */ 27988ebb749SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 28025084f0cSStefano Zampini /* Set values in local_auxmat2 */ 28125084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec2_R,&array);CHKERRQ(ierr); 28288ebb749SStefano Zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 28325084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec2_R,&array);CHKERRQ(ierr); 28488ebb749SStefano Zampini } 28588ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28688ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28725084f0cSStefano Zampini ierr = MatScale(pcbddc->local_auxmat2,m_one);CHKERRQ(ierr); 28888ebb749SStefano Zampini 28988ebb749SStefano Zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 29025084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 29125084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 29288ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 29388ebb749SStefano Zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 29488ebb749SStefano Zampini ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 29525084f0cSStefano Zampini ierr = MatSetUp(M1);CHKERRQ(ierr); 29625084f0cSStefano Zampini ierr = MatDuplicate(M1,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 29725084f0cSStefano Zampini ierr = MatZeroEntries(M2);CHKERRQ(ierr); 29825084f0cSStefano Zampini ierr = VecSet(vec1_C,m_one);CHKERRQ(ierr); 29925084f0cSStefano Zampini ierr = MatDiagonalSet(M2,vec1_C,INSERT_VALUES);CHKERRQ(ierr); 30025084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 30125084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 30225084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 30388ebb749SStefano Zampini /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 304f4ddd8eeSStefano Zampini if (!pcbddc->local_auxmat1) { 30588ebb749SStefano Zampini ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 306f4ddd8eeSStefano Zampini } else { 307f4ddd8eeSStefano Zampini ierr = MatMatMult(M1,C_CR,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 308f4ddd8eeSStefano Zampini } 30988ebb749SStefano Zampini } 31088ebb749SStefano Zampini 31188ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 31288ebb749SStefano Zampini if (n_vertices) { 3133a50541eSStefano Zampini PetscInt ibs,mbs; 3143a50541eSStefano Zampini PetscBool issbaij; 315af732b37SStefano Zampini Mat newmat; 3163a50541eSStefano Zampini 3173a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 3189577ea80SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 3199577ea80SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 3203a50541eSStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ */ 3219577ea80SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 3229577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 3239577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3249577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 3259577ea80SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 3269577ea80SStefano Zampini } else { 3273a50541eSStefano Zampini /* this is safe */ 3289577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 3293a50541eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 3303a50541eSStefano Zampini if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 3313a50541eSStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 33245a1bb75SStefano Zampini /* which of the two approaches is faster? */ 3333a50541eSStefano Zampini /* ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 3343a50541eSStefano Zampini ierr = MatCreateTranspose(A_RV,&A_VR);CHKERRQ(ierr);*/ 3353a50541eSStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3363a50541eSStefano Zampini ierr = MatCreateTranspose(A_VR,&A_RV);CHKERRQ(ierr); 3373a50541eSStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 3383a50541eSStefano Zampini } else { 3399577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 3409577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3419577ea80SStefano Zampini } 3423a50541eSStefano Zampini } 3432a7a6963SBarry Smith ierr = MatCreateVecs(A_RV,&vec1_V,NULL);CHKERRQ(ierr); 34445a1bb75SStefano Zampini ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 34525084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 34688ebb749SStefano Zampini } 34788ebb749SStefano Zampini 34888ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 349f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 350f4ddd8eeSStefano Zampini PetscInt on_B,on_primal; 351f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 352f4ddd8eeSStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size) { 353f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 354f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 355f4ddd8eeSStefano Zampini } 356f4ddd8eeSStefano Zampini } 357f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_D) { 358f4ddd8eeSStefano Zampini PetscInt on_D,on_primal; 359f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,&on_primal);CHKERRQ(ierr); 360f4ddd8eeSStefano Zampini if (on_D != n_D || on_primal != pcbddc->local_primal_size) { 361f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 362f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 363f4ddd8eeSStefano Zampini } 364f4ddd8eeSStefano Zampini } 365f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 36688ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 36788ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 36888ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 36925084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_phi_B);CHKERRQ(ierr); 370f4ddd8eeSStefano Zampini } 371f4ddd8eeSStefano Zampini if ( (pcbddc->switch_static || pcbddc->dbg_flag) && !pcbddc->coarse_phi_D ) { 37288ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 37388ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 37488ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 37525084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_phi_D);CHKERRQ(ierr); 37688ebb749SStefano Zampini } 37788ebb749SStefano Zampini 37825084f0cSStefano Zampini if (pcbddc->dbg_flag) { 3798ce42a96SStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idx_R_local);CHKERRQ(ierr); 380785e854fSJed Brown ierr = PetscMalloc1(2*pcbddc->local_primal_size,&coarsefunctions_errors);CHKERRQ(ierr); 381785e854fSJed Brown ierr = PetscMalloc1(2*pcbddc->local_primal_size,&constraints_errors);CHKERRQ(ierr); 38288ebb749SStefano Zampini } 38388ebb749SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 384854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 38588ebb749SStefano Zampini 38688ebb749SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 38725084f0cSStefano Zampini 38825084f0cSStefano Zampini /* vertices */ 38988ebb749SStefano Zampini for (i=0;i<n_vertices;i++) { 39045a1bb75SStefano Zampini /* this should not be needed, but MatMult_BAIJ is broken when using compressed row routines */ 391f4ddd8eeSStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); /* TODO: REMOVE IT */ 39288ebb749SStefano Zampini ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 39388ebb749SStefano Zampini ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 39488ebb749SStefano Zampini ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 39588ebb749SStefano Zampini ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 39625084f0cSStefano Zampini /* simplified solution of saddle point problem with null rhs on constraints multipliers */ 39788ebb749SStefano Zampini ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 39888ebb749SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 39988ebb749SStefano Zampini ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 40088ebb749SStefano Zampini if (n_constraints) { 40188ebb749SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 40288ebb749SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 40388ebb749SStefano Zampini ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 40488ebb749SStefano Zampini } 40588ebb749SStefano Zampini ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 40688ebb749SStefano Zampini ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 40788ebb749SStefano Zampini 40888ebb749SStefano Zampini /* Set values in coarse basis function and subdomain part of coarse_mat */ 40988ebb749SStefano Zampini /* coarse basis functions */ 41088ebb749SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 41188ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 41288ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 41325084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 41488ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 41525084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 41688ebb749SStefano Zampini ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 4178eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 41888ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 41988ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 42025084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 42188ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 42225084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 42388ebb749SStefano Zampini } 42425084f0cSStefano Zampini /* subdomain contribution to coarse matrix. WARNING -> column major ordering */ 42525084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 42625084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[i*pcbddc->local_primal_size],array,n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 42725084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 42888ebb749SStefano Zampini if (n_constraints) { 42925084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 43025084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[i*pcbddc->local_primal_size+n_vertices],array,n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 43125084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 43288ebb749SStefano Zampini } 43388ebb749SStefano Zampini 43425084f0cSStefano Zampini /* check */ 43525084f0cSStefano Zampini if (pcbddc->dbg_flag) { 43625084f0cSStefano Zampini /* assemble subdomain vector on local nodes */ 43788ebb749SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 43825084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 4399f00e9b4SStefano Zampini if (n_R) { 44025084f0cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,n_R,idx_R_local,array,INSERT_VALUES);CHKERRQ(ierr); 4419f00e9b4SStefano Zampini } 44225084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 443e9189074SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],one,INSERT_VALUES);CHKERRQ(ierr); 44425084f0cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 44525084f0cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 44688ebb749SStefano Zampini /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 44788ebb749SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 44825084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 44925084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_vertices,auxindices,array,INSERT_VALUES);CHKERRQ(ierr); 45025084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 45188ebb749SStefano Zampini if (n_constraints) { 45225084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 45325084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_constraints,&auxindices[n_vertices],array,INSERT_VALUES);CHKERRQ(ierr); 45425084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 45588ebb749SStefano Zampini } 45625084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 45725084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 45888ebb749SStefano Zampini ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 45988ebb749SStefano Zampini /* check saddle point solution */ 46088ebb749SStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 46188ebb749SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 46288ebb749SStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 46388ebb749SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 46425084f0cSStefano Zampini /* shift by the identity matrix */ 46525084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,i,m_one,ADD_VALUES);CHKERRQ(ierr); 46625084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 46725084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 46888ebb749SStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 46988ebb749SStefano Zampini } 47088ebb749SStefano Zampini } 47188ebb749SStefano Zampini 47225084f0cSStefano Zampini /* constraints */ 47388ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 47488ebb749SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 47588ebb749SStefano Zampini ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 47688ebb749SStefano Zampini ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 47788ebb749SStefano Zampini ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 47825084f0cSStefano Zampini /* simplified solution of saddle point problem with null rhs on vertices multipliers */ 47988ebb749SStefano Zampini ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 48088ebb749SStefano Zampini ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 48188ebb749SStefano Zampini ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 48225084f0cSStefano Zampini if (n_vertices) { 48325084f0cSStefano Zampini ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 48425084f0cSStefano Zampini } 48588ebb749SStefano Zampini /* Set values in coarse basis function and subdomain part of coarse_mat */ 48688ebb749SStefano Zampini /* coarse basis functions */ 48725084f0cSStefano Zampini j = i+n_vertices; /* don't touch this! */ 48888ebb749SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 48988ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49088ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49125084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 49225084f0cSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&j,array,INSERT_VALUES);CHKERRQ(ierr); 49325084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 4948eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 49588ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49688ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49725084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 49825084f0cSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&j,array,INSERT_VALUES);CHKERRQ(ierr); 49925084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 50088ebb749SStefano Zampini } 50125084f0cSStefano Zampini /* subdomain contribution to coarse matrix. WARNING -> column major ordering */ 50288ebb749SStefano Zampini if (n_vertices) { 50325084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 50425084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[j*pcbddc->local_primal_size],array,n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 50525084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 50688ebb749SStefano Zampini } 50725084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 50825084f0cSStefano Zampini ierr = PetscMemcpy(&coarse_submat_vals[j*pcbddc->local_primal_size+n_vertices],array,n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 50925084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 51088ebb749SStefano Zampini 51125084f0cSStefano Zampini if (pcbddc->dbg_flag) { 51288ebb749SStefano Zampini /* assemble subdomain vector on nodes */ 51388ebb749SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 51425084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 5159f00e9b4SStefano Zampini if (n_R) { 51625084f0cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,n_R,idx_R_local,array,INSERT_VALUES);CHKERRQ(ierr); 5179f00e9b4SStefano Zampini } 51825084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 51925084f0cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 52025084f0cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 52188ebb749SStefano Zampini /* assemble subdomain vector of lagrange multipliers */ 52288ebb749SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 52388ebb749SStefano Zampini if (n_vertices) { 52425084f0cSStefano Zampini ierr = VecGetArrayRead(vec2_V,&array);CHKERRQ(ierr); 52525084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_vertices,auxindices,array,INSERT_VALUES);CHKERRQ(ierr); 52625084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec2_V,&array);CHKERRQ(ierr); 52788ebb749SStefano Zampini } 52825084f0cSStefano Zampini ierr = VecGetArrayRead(vec1_C,&array);CHKERRQ(ierr); 52925084f0cSStefano Zampini ierr = VecSetValues(pcbddc->vec1_P,n_constraints,&auxindices[n_vertices],array,INSERT_VALUES);CHKERRQ(ierr); 53025084f0cSStefano Zampini ierr = VecRestoreArrayRead(vec1_C,&array);CHKERRQ(ierr); 53125084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 53225084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 53325084f0cSStefano Zampini ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 53488ebb749SStefano Zampini /* check saddle point solution */ 53588ebb749SStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 53688ebb749SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 53725084f0cSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[j]);CHKERRQ(ierr); 53888ebb749SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 53925084f0cSStefano Zampini /* shift by the identity matrix */ 54025084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,j,m_one,ADD_VALUES);CHKERRQ(ierr); 54125084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 54225084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 54325084f0cSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[j]);CHKERRQ(ierr); 54488ebb749SStefano Zampini } 54588ebb749SStefano Zampini } 54625084f0cSStefano Zampini /* call assembling routines for local coarse basis */ 54788ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 54888ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5498eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 55088ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55188ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55288ebb749SStefano Zampini } 55325084f0cSStefano Zampini 55488ebb749SStefano Zampini /* compute other basis functions for non-symmetric problems */ 555b9d89cd5SStefano Zampini if (!pcbddc->issym) { 556f4ddd8eeSStefano Zampini if (!pcbddc->coarse_psi_B) { 55788ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 55888ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 55988ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_B,impMatType);CHKERRQ(ierr); 56025084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_psi_B);CHKERRQ(ierr); 561f4ddd8eeSStefano Zampini } 562f4ddd8eeSStefano Zampini if ( (pcbddc->switch_static || pcbddc->dbg_flag) && !pcbddc->coarse_psi_D) { 56388ebb749SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 56488ebb749SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 56588ebb749SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_D,impMatType);CHKERRQ(ierr); 56625084f0cSStefano Zampini ierr = MatSetUp(pcbddc->coarse_psi_D);CHKERRQ(ierr); 56788ebb749SStefano Zampini } 56888ebb749SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 56988ebb749SStefano Zampini if (n_constraints) { 57088ebb749SStefano Zampini ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 57188ebb749SStefano Zampini for (j=0;j<n_constraints;j++) { 57225084f0cSStefano Zampini ierr = VecSetValue(vec1_C,j,coarse_submat_vals[(j+n_vertices)*pcbddc->local_primal_size+i],INSERT_VALUES);CHKERRQ(ierr); 57388ebb749SStefano Zampini } 57425084f0cSStefano Zampini ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 57525084f0cSStefano Zampini ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 57688ebb749SStefano Zampini } 57788ebb749SStefano Zampini if (i<n_vertices) { 57888ebb749SStefano Zampini ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 57988ebb749SStefano Zampini ierr = VecSetValue(vec1_V,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 58088ebb749SStefano Zampini ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 58188ebb749SStefano Zampini ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 58288ebb749SStefano Zampini ierr = MatMultTranspose(A_VR,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 58388ebb749SStefano Zampini if (n_constraints) { 58488ebb749SStefano Zampini ierr = MatMultTransposeAdd(C_CR,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 58588ebb749SStefano Zampini } 58688ebb749SStefano Zampini } else { 58788ebb749SStefano Zampini ierr = MatMultTranspose(C_CR,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 58888ebb749SStefano Zampini } 58988ebb749SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 59088ebb749SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 59188ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 59288ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 59325084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 59488ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 59525084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_B,&array);CHKERRQ(ierr); 59688ebb749SStefano Zampini if (i<n_vertices) { 59788ebb749SStefano Zampini ierr = MatSetValue(pcbddc->coarse_psi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 59888ebb749SStefano Zampini } 5998eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 60088ebb749SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60188ebb749SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60225084f0cSStefano Zampini ierr = VecGetArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 60388ebb749SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 60425084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcis->vec1_D,&array);CHKERRQ(ierr); 60588ebb749SStefano Zampini } 60688ebb749SStefano Zampini 60725084f0cSStefano Zampini if (pcbddc->dbg_flag) { 60888ebb749SStefano Zampini /* assemble subdomain vector on nodes */ 60988ebb749SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 61025084f0cSStefano Zampini ierr = VecGetArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 6119f00e9b4SStefano Zampini if (n_R) { 61225084f0cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,n_R,idx_R_local,array,INSERT_VALUES);CHKERRQ(ierr); 6139f00e9b4SStefano Zampini } 61425084f0cSStefano Zampini ierr = VecRestoreArrayRead(pcbddc->vec1_R,&array);CHKERRQ(ierr); 61525084f0cSStefano Zampini if (i<n_vertices) { 616e9189074SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],one,INSERT_VALUES);CHKERRQ(ierr); 61788ebb749SStefano Zampini } 61825084f0cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 61925084f0cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 62025084f0cSStefano Zampini /* assemble subdomain vector of lagrange multipliers */ 62125084f0cSStefano Zampini for (j=0;j<pcbddc->local_primal_size;j++) { 62225084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,j,-coarse_submat_vals[j*pcbddc->local_primal_size+i],INSERT_VALUES);CHKERRQ(ierr); 62325084f0cSStefano Zampini } 62425084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 62525084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 62688ebb749SStefano Zampini /* check saddle point solution */ 62788ebb749SStefano Zampini ierr = MatMultTranspose(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 62888ebb749SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 62988ebb749SStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 63088ebb749SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 63125084f0cSStefano Zampini /* shift by the identity matrix */ 63225084f0cSStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,i,m_one,ADD_VALUES);CHKERRQ(ierr); 63325084f0cSStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 63425084f0cSStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 63588ebb749SStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 63688ebb749SStefano Zampini } 63788ebb749SStefano Zampini } 63888ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 63988ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6408eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 64188ebb749SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 64288ebb749SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 64388ebb749SStefano Zampini } 644c0553b1fSStefano Zampini unsymmetric_check = PETSC_TRUE; 645c0553b1fSStefano Zampini } else { /* take references to already computed coarse basis */ 646c0553b1fSStefano Zampini unsymmetric_check = PETSC_FALSE; 647c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 648c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 649c0553b1fSStefano Zampini if (pcbddc->coarse_phi_D) { 650c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 651c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 652c0553b1fSStefano Zampini } 65388ebb749SStefano Zampini } 65488ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 65588ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 65688ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 65788ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 65825084f0cSStefano Zampini if (pcbddc->dbg_flag) { 65988ebb749SStefano Zampini Mat coarse_sub_mat; 66025084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 66188ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 66288ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 66388ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 66488ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 66588ebb749SStefano Zampini PetscReal real_value; 66688ebb749SStefano Zampini 66788ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 66888ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 66988ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 67088ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 67188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 67288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 673c0553b1fSStefano Zampini if (unsymmetric_check) { 67488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 67588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 67688ebb749SStefano Zampini } 67788ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 67888ebb749SStefano Zampini 67925084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 68025084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 68125084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 682c0553b1fSStefano Zampini if (unsymmetric_check) { 68388ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 68488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 68588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 68688ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 68788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 68888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 68988ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 69088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 69188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 69288ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 69388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 69488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 69588ebb749SStefano Zampini } else { 69688ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 69788ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 69888ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 69988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 70088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 70188ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 70288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 70388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 70488ebb749SStefano Zampini } 70588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 70688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 70788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 70888ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 70981d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 71088ebb749SStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&real_value);CHKERRQ(ierr); 7110fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 71225084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"----------------------------------\n");CHKERRQ(ierr); 71325084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 71425084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"matrix error = % 1.14e\n",real_value);CHKERRQ(ierr); 71525084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"coarse functions (phi) errors\n");CHKERRQ(ierr); 71688ebb749SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 71725084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); 71888ebb749SStefano Zampini } 71925084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"constraints (phi) errors\n");CHKERRQ(ierr); 72088ebb749SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 72125084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); 72288ebb749SStefano Zampini } 723c0553b1fSStefano Zampini if (unsymmetric_check) { 72425084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"coarse functions (psi) errors\n");CHKERRQ(ierr); 72588ebb749SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 72625084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,coarsefunctions_errors[i]);CHKERRQ(ierr); 72788ebb749SStefano Zampini } 72825084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"constraints (psi) errors\n");CHKERRQ(ierr); 72988ebb749SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 73025084f0cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,constraints_errors[i]);CHKERRQ(ierr); 73188ebb749SStefano Zampini } 73288ebb749SStefano Zampini } 73325084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 73488ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 73588ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 73688ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 73788ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 73888ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 73988ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 74088ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 74188ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 74288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 74388ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 744c0553b1fSStefano Zampini if (unsymmetric_check) { 74588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 74688ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 74788ebb749SStefano Zampini } 74888ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 7498ce42a96SStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idx_R_local);CHKERRQ(ierr); 75088ebb749SStefano Zampini ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 75188ebb749SStefano Zampini ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 75288ebb749SStefano Zampini } 75388ebb749SStefano Zampini /* free memory */ 75488ebb749SStefano Zampini if (n_vertices) { 75588ebb749SStefano Zampini ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 75688ebb749SStefano Zampini ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 75788ebb749SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 75888ebb749SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 75988ebb749SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 76088ebb749SStefano Zampini } 76188ebb749SStefano Zampini if (n_constraints) { 76288ebb749SStefano Zampini ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 76388ebb749SStefano Zampini ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 76488ebb749SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 76588ebb749SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 76688ebb749SStefano Zampini } 76788ebb749SStefano Zampini ierr = PetscFree(auxindices);CHKERRQ(ierr); 7688629588bSStefano Zampini /* get back data */ 7698629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 77088ebb749SStefano Zampini PetscFunctionReturn(0); 77188ebb749SStefano Zampini } 77288ebb749SStefano Zampini 77388ebb749SStefano Zampini #undef __FUNCT__ 774*d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 775*d65f70fdSStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 776*d65f70fdSStefano Zampini { 777*d65f70fdSStefano Zampini Mat *work_mat; 778*d65f70fdSStefano Zampini IS isrow_s,iscol_s; 779*d65f70fdSStefano Zampini PetscBool rsorted,csorted; 780*d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 781*d65f70fdSStefano Zampini PetscErrorCode ierr; 782*d65f70fdSStefano Zampini 783*d65f70fdSStefano Zampini PetscFunctionBegin; 784*d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 785*d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 786*d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 787*d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 788*d65f70fdSStefano Zampini 789*d65f70fdSStefano Zampini if (!rsorted) { 790*d65f70fdSStefano Zampini const PetscInt *idxs; 791*d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 792*d65f70fdSStefano Zampini 793*d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 794*d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 795*d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 796*d65f70fdSStefano Zampini idxs_perm_r[i] = i; 797*d65f70fdSStefano Zampini } 798*d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 799*d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 800*d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 801*d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 802*d65f70fdSStefano Zampini } 803*d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 804*d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 805*d65f70fdSStefano Zampini } else { 806*d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 807*d65f70fdSStefano Zampini isrow_s = isrow; 808*d65f70fdSStefano Zampini } 809*d65f70fdSStefano Zampini 810*d65f70fdSStefano Zampini if (!csorted) { 811*d65f70fdSStefano Zampini if (isrow == iscol) { 812*d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 813*d65f70fdSStefano Zampini iscol_s = isrow_s; 814*d65f70fdSStefano Zampini } else { 815*d65f70fdSStefano Zampini const PetscInt *idxs; 816*d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 817*d65f70fdSStefano Zampini 818*d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 819*d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 820*d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 821*d65f70fdSStefano Zampini idxs_perm_c[i] = i; 822*d65f70fdSStefano Zampini } 823*d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 824*d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 825*d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 826*d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 827*d65f70fdSStefano Zampini } 828*d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 829*d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 830*d65f70fdSStefano Zampini } 831*d65f70fdSStefano Zampini } else { 832*d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 833*d65f70fdSStefano Zampini iscol_s = iscol; 834*d65f70fdSStefano Zampini } 835*d65f70fdSStefano Zampini 836*d65f70fdSStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 837*d65f70fdSStefano Zampini 838*d65f70fdSStefano Zampini if (!rsorted || !csorted) { 839*d65f70fdSStefano Zampini Mat new_mat; 840*d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 841*d65f70fdSStefano Zampini 842*d65f70fdSStefano Zampini if (!rsorted) { 843*d65f70fdSStefano Zampini PetscInt *idxs_r,i; 844*d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 845*d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 846*d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 847*d65f70fdSStefano Zampini } 848*d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 849*d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 850*d65f70fdSStefano Zampini } else { 851*d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 852*d65f70fdSStefano Zampini } 853*d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 854*d65f70fdSStefano Zampini 855*d65f70fdSStefano Zampini if (!csorted) { 856*d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 857*d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 858*d65f70fdSStefano Zampini is_perm_c = is_perm_r; 859*d65f70fdSStefano Zampini } else { 860*d65f70fdSStefano Zampini PetscInt *idxs_c,i; 861*d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 862*d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 863*d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 864*d65f70fdSStefano Zampini } 865*d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 866*d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 867*d65f70fdSStefano Zampini } 868*d65f70fdSStefano Zampini } else { 869*d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 870*d65f70fdSStefano Zampini } 871*d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 872*d65f70fdSStefano Zampini 873*d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 874*d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 875*d65f70fdSStefano Zampini work_mat[0] = new_mat; 876*d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 877*d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 878*d65f70fdSStefano Zampini } 879*d65f70fdSStefano Zampini 880*d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 881*d65f70fdSStefano Zampini *B = work_mat[0]; 882*d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 883*d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 884*d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 885*d65f70fdSStefano Zampini PetscFunctionReturn(0); 886*d65f70fdSStefano Zampini } 887*d65f70fdSStefano Zampini 888*d65f70fdSStefano Zampini #undef __FUNCT__ 8895e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 8905e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 891aa0d41d4SStefano Zampini { 892aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8935e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 894*d65f70fdSStefano Zampini Mat new_mat; 8955e8657edSStefano Zampini IS is_local,is_global; 896*d65f70fdSStefano Zampini PetscInt local_size; 897*d65f70fdSStefano Zampini PetscBool isseqaij; 898aa0d41d4SStefano Zampini PetscErrorCode ierr; 899aa0d41d4SStefano Zampini 900aa0d41d4SStefano Zampini PetscFunctionBegin; 901aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 9025e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 9035e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 904906d46d4SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(matis->mapping,is_local,&is_global);CHKERRQ(ierr); 905906d46d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 906*d65f70fdSStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 907906d46d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 908906d46d4SStefano Zampini 909906d46d4SStefano Zampini /* check */ 910906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 911906d46d4SStefano Zampini Vec x,x_change; 912906d46d4SStefano Zampini PetscReal error; 913906d46d4SStefano Zampini 9145e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 915906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 9165e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 9175e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9185e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 919*d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 9205e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9215e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 922906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 923906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 924906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 925906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 926906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 927906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 928906d46d4SStefano Zampini } 929906d46d4SStefano Zampini 93022d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 9319b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 93222d5777bSStefano Zampini if (isseqaij) { 933*d65f70fdSStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 934aa0d41d4SStefano Zampini } else { 935aa0d41d4SStefano Zampini Mat work_mat; 936aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 937*d65f70fdSStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 938aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 939aa0d41d4SStefano Zampini } 940*d65f70fdSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 94145a1bb75SStefano Zampini /* 94245a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 943*d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 94445a1bb75SStefano Zampini */ 945*d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 946aa0d41d4SStefano Zampini PetscFunctionReturn(0); 947aa0d41d4SStefano Zampini } 948aa0d41d4SStefano Zampini 949aa0d41d4SStefano Zampini #undef __FUNCT__ 950a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 9518ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 952a64d13efSStefano Zampini { 953a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 954a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 9558ce42a96SStefano Zampini IS is_aux1,is_aux2; 956e9189074SStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 9573a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 9583a50541eSStefano Zampini PetscInt vbs,bs; 9594641a718SStefano Zampini PetscBT bitmask; 960a64d13efSStefano Zampini PetscErrorCode ierr; 961a64d13efSStefano Zampini 962a64d13efSStefano Zampini PetscFunctionBegin; 963b23d619eSStefano Zampini /* 964b23d619eSStefano Zampini No need to setup local scatters if 965b23d619eSStefano Zampini - primal space is unchanged 966b23d619eSStefano Zampini AND 967b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 968b23d619eSStefano Zampini AND 969b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 970b23d619eSStefano Zampini */ 971b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 972f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 973f4ddd8eeSStefano Zampini } 974f4ddd8eeSStefano Zampini /* destroy old objects */ 975f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 976f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 977f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 978a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 979a64d13efSStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 980e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 9814641a718SStefano Zampini /* create auxiliary bitmask */ 9824641a718SStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 9834641a718SStefano Zampini for (i=0;i<n_vertices;i++) { 984e9189074SStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->primal_indices_local_idxs[i]);CHKERRQ(ierr); 9854641a718SStefano Zampini } 9863a50541eSStefano Zampini 987a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 988854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 989a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 9904641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 991a64d13efSStefano Zampini idx_R_local[n_R] = i; 992a64d13efSStefano Zampini n_R++; 993a64d13efSStefano Zampini } 994a64d13efSStefano Zampini } 9953a50541eSStefano Zampini 9963a50541eSStefano Zampini /* Block code */ 9973a50541eSStefano Zampini vbs = 1; 9983a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 9993a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 10003a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 10013a50541eSStefano Zampini PetscInt *vary; 10023a50541eSStefano Zampini /* Verify if the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 1003785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 10043a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 1005e9189074SStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->primal_indices_local_idxs[i]/bs]++; 10063a50541eSStefano Zampini for (i=0; i<n_vertices; i++) { 10073a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 10083a50541eSStefano Zampini is_blocked = PETSC_FALSE; 10093a50541eSStefano Zampini break; 10103a50541eSStefano Zampini } 10113a50541eSStefano Zampini } 10123a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 10133a50541eSStefano Zampini vbs = bs; 10143a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 10153a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 10163a50541eSStefano Zampini } 10173a50541eSStefano Zampini } 10183a50541eSStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 10193a50541eSStefano Zampini } 10203a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 10213a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 1022a64d13efSStefano Zampini 1023a64d13efSStefano Zampini /* print some info if requested */ 1024a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 1025a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1026a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 10270fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1028a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 1029a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 10303a50541eSStefano 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); 1031a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 1032a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1033a64d13efSStefano Zampini } 1034a64d13efSStefano Zampini 1035a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 10363a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1037854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 1038854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 1039a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 10404641a718SStefano Zampini for (i=0; i<n_D; i++) { 10414641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 10424641a718SStefano Zampini } 1043a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1044a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 10454641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 10464641a718SStefano Zampini aux_array1[j++] = i; 1047a64d13efSStefano Zampini } 1048a64d13efSStefano Zampini } 1049a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1050a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1051a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 10524641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 10534641a718SStefano Zampini aux_array2[j++] = i; 1054a64d13efSStefano Zampini } 1055a64d13efSStefano Zampini } 1056a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1057a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 1058a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 1059a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1060a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 1061a64d13efSStefano Zampini 10628eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1063785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 1064a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 10654641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 10664641a718SStefano Zampini aux_array1[j++] = i; 1067a64d13efSStefano Zampini } 1068a64d13efSStefano Zampini } 1069a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1070a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 1071a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1072a64d13efSStefano Zampini } 10734641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 10743a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1075a64d13efSStefano Zampini PetscFunctionReturn(0); 1076a64d13efSStefano Zampini } 1077a64d13efSStefano Zampini 1078304d26faSStefano Zampini 1079304d26faSStefano Zampini #undef __FUNCT__ 1080304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 1081684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 1082304d26faSStefano Zampini { 1083304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1084304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1085304d26faSStefano Zampini PC pc_temp; 1086304d26faSStefano Zampini Mat A_RR; 1087f4ddd8eeSStefano Zampini MatReuse reuse; 1088304d26faSStefano Zampini PetscScalar m_one = -1.0; 1089304d26faSStefano Zampini PetscReal value; 1090af732b37SStefano Zampini PetscInt n_D,n_R,ibs,mbs; 10919577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 1092304d26faSStefano Zampini PetscErrorCode ierr; 1093e604994aSStefano Zampini /* prefixes stuff */ 1094312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 1095e604994aSStefano Zampini size_t len; 1096304d26faSStefano Zampini 1097304d26faSStefano Zampini PetscFunctionBegin; 1098304d26faSStefano Zampini 1099e604994aSStefano Zampini /* compute prefixes */ 1100e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 1101e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 1102e604994aSStefano Zampini if (!pcbddc->current_level) { 1103e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1104e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1105e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1106e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1107e604994aSStefano Zampini } else { 1108e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 1109312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 1110e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 1111e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 1112312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 1113312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 111434d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 111534d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 1116e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1117e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1118e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 1119e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 1120e604994aSStefano Zampini } 1121e604994aSStefano Zampini 1122304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 1123684f6988SStefano Zampini if (dirichlet) { 1124ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 11258ce42a96SStefano Zampini ierr = ISGetSize(pcis->is_I_local,&n_D);CHKERRQ(ierr); 1126304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 1127304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 1128304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 1129304d26faSStefano Zampini /* default */ 1130304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1131e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 11329577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1133304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 11349577ea80SStefano Zampini if (issbaij) { 11359577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 11369577ea80SStefano Zampini } else { 1137304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 11389577ea80SStefano Zampini } 1139304d26faSStefano Zampini /* Allow user's customization */ 1140304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1141304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1142304d26faSStefano Zampini } 1143d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 1144304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1145304d26faSStefano Zampini if (!n_D) { 1146304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 1147304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1148304d26faSStefano Zampini } 1149304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 1150304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1151304d26faSStefano Zampini /* set ksp_D into pcis data */ 1152304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 1153304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 1154304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 1155684f6988SStefano Zampini } 1156304d26faSStefano Zampini 1157304d26faSStefano Zampini /* NEUMANN PROBLEM */ 1158684f6988SStefano Zampini A_RR = 0; 1159684f6988SStefano Zampini if (neumann) { 1160f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 11618ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 1162f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 1163f4ddd8eeSStefano Zampini PetscInt nn_R; 116481d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 1165f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1166f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 1167f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 1168f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 1169f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1170f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1171f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 1172727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 1173f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1174f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1175f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 1176f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 1177f4ddd8eeSStefano Zampini } 1178f4ddd8eeSStefano Zampini } 1179f4ddd8eeSStefano Zampini /* last check */ 1180d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 1181f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1182f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1183f4ddd8eeSStefano Zampini } 1184f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 1185f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1186f4ddd8eeSStefano Zampini } 1187f4ddd8eeSStefano Zampini /* extract A_RR */ 1188af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 1189af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 11903a50541eSStefano Zampini if (ibs != mbs) { 1191af732b37SStefano Zampini Mat newmat; 1192af732b37SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 1193f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1194af732b37SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 1195af732b37SStefano Zampini } else { 1196f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1197af732b37SStefano Zampini } 1198f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 1199304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 1200304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 1201304d26faSStefano Zampini /* default */ 1202304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1203e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 1204304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 12059577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 12069577ea80SStefano Zampini if (issbaij) { 12079577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 12089577ea80SStefano Zampini } else { 1209304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 12109577ea80SStefano Zampini } 1211304d26faSStefano Zampini /* Allow user's customization */ 1212304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1213304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1214304d26faSStefano Zampini } 1215d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 1216304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1217304d26faSStefano Zampini if (!n_R) { 1218304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 1219304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1220304d26faSStefano Zampini } 1221304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 1222304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1223684f6988SStefano Zampini } 1224304d26faSStefano Zampini 1225304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 12260fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 1227684f6988SStefano Zampini if (pcbddc->dbg_flag) { 1228684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1229684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1230684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1231684f6988SStefano Zampini } 1232684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 12330fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 12340fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 12350fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 12360fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 12370fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 1238304d26faSStefano Zampini /* need to be adapted? */ 1239b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1240b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1241b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 1242304d26faSStefano Zampini /* print info */ 1243304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1244e604994aSStefano 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); 1245304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1246304d26faSStefano Zampini } 1247b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 12488ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcis->is_I_local);CHKERRQ(ierr); 1249304d26faSStefano Zampini } 1250684f6988SStefano Zampini } 1251684f6988SStefano Zampini if (neumann) { /* Neumann */ 12520fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 12530fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 12540fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 12550fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 12560fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 1257304d26faSStefano Zampini /* need to be adapted? */ 1258b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1259b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1260304d26faSStefano Zampini /* print info */ 1261304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1262e604994aSStefano 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); 1263304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1264304d26faSStefano Zampini } 1265b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 12668ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcbddc->is_R_local);CHKERRQ(ierr); 1267304d26faSStefano Zampini } 12680fccc4e9SStefano Zampini } 1269684f6988SStefano Zampini } 1270304d26faSStefano Zampini /* free Neumann problem's matrix */ 1271304d26faSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1272304d26faSStefano Zampini PetscFunctionReturn(0); 1273304d26faSStefano Zampini } 1274304d26faSStefano Zampini 1275304d26faSStefano Zampini #undef __FUNCT__ 1276ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 127720c7b377SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec rhs, Vec sol, Vec work, PetscBool applytranspose) 1278674ae819SStefano Zampini { 1279674ae819SStefano Zampini PetscErrorCode ierr; 1280674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1281674ae819SStefano Zampini 1282674ae819SStefano Zampini PetscFunctionBegin; 128320c7b377SStefano Zampini if (applytranspose) { 1284674ae819SStefano Zampini if (pcbddc->local_auxmat1) { 128520c7b377SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,rhs,work);CHKERRQ(ierr); 128620c7b377SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,work,rhs,rhs);CHKERRQ(ierr); 128720c7b377SStefano Zampini } 128820c7b377SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 128920c7b377SStefano Zampini } else { 129020c7b377SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 129120c7b377SStefano Zampini if (pcbddc->local_auxmat1) { 129220c7b377SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,sol,work);CHKERRQ(ierr); 129320c7b377SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,work,sol,sol);CHKERRQ(ierr); 129420c7b377SStefano Zampini } 1295674ae819SStefano Zampini } 1296674ae819SStefano Zampini PetscFunctionReturn(0); 1297674ae819SStefano Zampini } 1298674ae819SStefano Zampini 1299dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 1300674ae819SStefano Zampini #undef __FUNCT__ 1301674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 1302dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 1303674ae819SStefano Zampini { 1304674ae819SStefano Zampini PetscErrorCode ierr; 1305674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1306674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 1307674ae819SStefano Zampini const PetscScalar zero = 0.0; 1308674ae819SStefano Zampini 1309674ae819SStefano Zampini PetscFunctionBegin; 1310dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 1311dc359a40SStefano Zampini if (applytranspose) { 1312674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 13138eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 1314dc359a40SStefano Zampini } else { 1315674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 1316674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 131715aaf578SStefano Zampini } 131812edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 131912edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 132012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 132112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 132212edc857SStefano Zampini 13239f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 132412edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 132512edc857SStefano Zampini if (pcbddc->coarse_ksp) { 132612edc857SStefano Zampini if (applytranspose) { 132712edc857SStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 132812edc857SStefano Zampini } else { 132912edc857SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 133012edc857SStefano Zampini } 133112edc857SStefano Zampini } 1332674ae819SStefano Zampini 1333674ae819SStefano Zampini /* Local solution on R nodes */ 13349f00e9b4SStefano Zampini if (pcis->n) { 1335674ae819SStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 1336674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1337674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13388eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1339674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1340674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1341674ae819SStefano Zampini } 134220c7b377SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcbddc->vec1_R,pcbddc->vec2_R,pcbddc->vec1_C,applytranspose);CHKERRQ(ierr); 1343674ae819SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1344674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1345674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13468eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1347674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1348674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1349674ae819SStefano Zampini } 13509f00e9b4SStefano Zampini } 1351674ae819SStefano Zampini 13529f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 13539f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 135412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1355674ae819SStefano Zampini 1356674ae819SStefano Zampini /* Sum contributions from two levels */ 1357dc359a40SStefano Zampini if (applytranspose) { 1358dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 1359dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1360dc359a40SStefano Zampini } else { 1361674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 13628eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1363dc359a40SStefano Zampini } 1364674ae819SStefano Zampini PetscFunctionReturn(0); 1365674ae819SStefano Zampini } 1366674ae819SStefano Zampini 136712edc857SStefano Zampini /* TODO: the following two function can be optimized using VecPlaceArray whenever possible and using overlap flag */ 1368674ae819SStefano Zampini #undef __FUNCT__ 1369674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 137012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 1371674ae819SStefano Zampini { 1372674ae819SStefano Zampini PetscErrorCode ierr; 1373674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 137412edc857SStefano Zampini PetscScalar *array,*array2; 137512edc857SStefano Zampini Vec from,to; 1376674ae819SStefano Zampini 1377674ae819SStefano Zampini PetscFunctionBegin; 137812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 137912edc857SStefano Zampini from = pcbddc->coarse_vec; 138012edc857SStefano Zampini to = pcbddc->vec1_P; 138112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 138212edc857SStefano Zampini Vec tvec; 138312edc857SStefano Zampini PetscInt lsize; 138412edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 138512edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 138612edc857SStefano Zampini ierr = VecGetArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 138712edc857SStefano Zampini ierr = VecGetArray(from,&array2);CHKERRQ(ierr); 138812edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 138912edc857SStefano Zampini ierr = VecRestoreArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 139012edc857SStefano Zampini ierr = VecRestoreArray(from,&array2);CHKERRQ(ierr); 139112edc857SStefano Zampini } 139212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 139312edc857SStefano Zampini from = pcbddc->vec1_P; 139412edc857SStefano Zampini to = pcbddc->coarse_vec; 139512edc857SStefano Zampini } 139612edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 1397674ae819SStefano Zampini PetscFunctionReturn(0); 1398674ae819SStefano Zampini } 1399674ae819SStefano Zampini 1400674ae819SStefano Zampini #undef __FUNCT__ 1401674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 140212edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 1403674ae819SStefano Zampini { 1404674ae819SStefano Zampini PetscErrorCode ierr; 1405674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 140612edc857SStefano Zampini PetscScalar *array,*array2; 140712edc857SStefano Zampini Vec from,to; 1408674ae819SStefano Zampini 1409674ae819SStefano Zampini PetscFunctionBegin; 141012edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 141112edc857SStefano Zampini from = pcbddc->coarse_vec; 141212edc857SStefano Zampini to = pcbddc->vec1_P; 141312edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 141412edc857SStefano Zampini from = pcbddc->vec1_P; 141512edc857SStefano Zampini to = pcbddc->coarse_vec; 141612edc857SStefano Zampini } 141712edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 141812edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 141912edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 142012edc857SStefano Zampini Vec tvec; 142112edc857SStefano Zampini PetscInt lsize; 142212edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 142312edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 142412edc857SStefano Zampini ierr = VecGetArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 142512edc857SStefano Zampini ierr = VecGetArray(tvec,&array2);CHKERRQ(ierr); 142612edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 142712edc857SStefano Zampini ierr = VecRestoreArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 142812edc857SStefano Zampini ierr = VecRestoreArray(tvec,&array2);CHKERRQ(ierr); 142912edc857SStefano Zampini } 143012edc857SStefano Zampini } 1431674ae819SStefano Zampini PetscFunctionReturn(0); 1432674ae819SStefano Zampini } 1433674ae819SStefano Zampini 1434984c4197SStefano Zampini /* uncomment for testing purposes */ 1435984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 1436674ae819SStefano Zampini #undef __FUNCT__ 1437674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 1438674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 1439674ae819SStefano Zampini { 1440674ae819SStefano Zampini PetscErrorCode ierr; 1441674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1442674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1443674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1444984c4197SStefano Zampini /* constraint and (optionally) change of basis matrix implemented as SeqAIJ */ 1445674ae819SStefano Zampini MatType impMatType=MATSEQAIJ; 1446984c4197SStefano Zampini /* one and zero */ 1447984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 1448984c4197SStefano Zampini /* space to store constraints and their local indices */ 1449984c4197SStefano Zampini PetscScalar *temp_quadrature_constraint; 1450984c4197SStefano Zampini PetscInt *temp_indices,*temp_indices_to_constraint,*temp_indices_to_constraint_B; 1451984c4197SStefano Zampini /* iterators */ 1452984c4197SStefano Zampini PetscInt i,j,k,total_counts,temp_start_ptr; 1453984c4197SStefano Zampini /* stuff to store connected components stored in pcbddc->mat_graph */ 1454984c4197SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges,*used_IS; 1455984c4197SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges; 1456984c4197SStefano Zampini /* near null space stuff */ 1457674ae819SStefano Zampini MatNullSpace nearnullsp; 1458674ae819SStefano Zampini const Vec *nearnullvecs; 1459674ae819SStefano Zampini Vec *localnearnullsp; 1460984c4197SStefano Zampini PetscBool nnsp_has_cnst; 1461984c4197SStefano Zampini PetscInt nnsp_size; 1462984c4197SStefano Zampini PetscScalar *array; 1463984c4197SStefano Zampini /* BLAS integers */ 1464e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 1465e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 1466c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 1467984c4197SStefano Zampini /* LAPACK working arrays for SVD or POD */ 1468242a89d7SStefano Zampini PetscBool skip_lapack; 1469984c4197SStefano Zampini PetscScalar *work; 1470984c4197SStefano Zampini PetscReal *singular_vals; 1471984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1472984c4197SStefano Zampini PetscReal *rwork; 1473674ae819SStefano Zampini #endif 1474984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1475e310c8b4SStefano Zampini PetscBLASInt Blas_one_2=1; 1476984c4197SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 1477b7d8b9f8SStefano Zampini #else 1478b7d8b9f8SStefano Zampini PetscBLASInt dummy_int_1=1,dummy_int_2=1; 1479b7d8b9f8SStefano Zampini PetscScalar dummy_scalar_1=0.0,dummy_scalar_2=0.0; 1480984c4197SStefano Zampini #endif 1481727cdba6SStefano Zampini /* reuse */ 1482727cdba6SStefano Zampini PetscInt olocal_primal_size; 1483727cdba6SStefano Zampini PetscInt *oprimal_indices_local_idxs; 1484984c4197SStefano Zampini /* change of basis */ 1485984c4197SStefano Zampini PetscInt *aux_primal_numbering,*aux_primal_minloc,*global_indices; 1486a717540cSStefano Zampini PetscBool boolforchange,qr_needed; 1487a717540cSStefano Zampini PetscBT touched,change_basis,qr_needed_idx; 1488984c4197SStefano Zampini /* auxiliary stuff */ 148939e2fb2aSStefano Zampini PetscInt *nnz,*is_indices,*aux_primal_numbering_B; 1490911cabfeSStefano Zampini PetscInt ncc,*gidxs,*permutation,*temp_indices_to_constraint_work; 1491911cabfeSStefano Zampini PetscScalar *temp_quadrature_constraint_work; 1492984c4197SStefano Zampini /* some quantities */ 149345a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 1494984c4197SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint,max_constraints,temp_constraints; 1495984c4197SStefano Zampini 1496674ae819SStefano Zampini 1497674ae819SStefano Zampini PetscFunctionBegin; 14988e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 14998e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 15008e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1501674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 1502d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 1503d06fc5fdSStefano Zampini /* free unneeded index sets */ 1504d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 1505d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 1506674ae819SStefano Zampini } 1507d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 1508d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 1509d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 1510d06fc5fdSStefano Zampini } 1511d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 1512d06fc5fdSStefano Zampini n_ISForEdges = 0; 1513d06fc5fdSStefano Zampini } 1514d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 1515d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 1516d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 1517d06fc5fdSStefano Zampini } 1518d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 1519d06fc5fdSStefano Zampini n_ISForFaces = 0; 1520d06fc5fdSStefano Zampini } 1521d06fc5fdSStefano Zampini /* HACKS (the following two blocks of code) */ 1522b9b85e73SStefano Zampini if (!ISForVertices && pcbddc->NullSpace && !pcbddc->user_ChangeOfBasisMatrix) { 1523b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1524d06fc5fdSStefano Zampini if (!ISForEdges) { 1525d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 1526d06fc5fdSStefano Zampini } 1527b8ffe317SStefano Zampini } 152898a51de6SStefano Zampini if (pcbddc->NullSpace) { 152998a51de6SStefano Zampini /* use_change_of_basis should be consistent among processors */ 1530d06fc5fdSStefano Zampini PetscBool tbool[2],gbool[2]; 1531d06fc5fdSStefano Zampini tbool [0] = pcbddc->use_change_of_basis; 1532d06fc5fdSStefano Zampini tbool [1] = pcbddc->use_change_on_faces; 1533d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1534d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 1535d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 153698a51de6SStefano Zampini } 1537984c4197SStefano Zampini /* print some info */ 1538674ae819SStefano Zampini if (pcbddc->dbg_flag) { 15390fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1540674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 1541674ae819SStefano Zampini i = 0; 1542674ae819SStefano Zampini if (ISForVertices) { 1543674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&i);CHKERRQ(ierr); 1544674ae819SStefano Zampini } 1545674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices\n",PetscGlobalRank,i);CHKERRQ(ierr); 1546674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges\n",PetscGlobalRank,n_ISForEdges);CHKERRQ(ierr); 154715aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces\n",PetscGlobalRank,n_ISForFaces);CHKERRQ(ierr); 1548674ae819SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1549674ae819SStefano Zampini } 1550674ae819SStefano Zampini /* check if near null space is attached to global mat */ 1551674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 1552674ae819SStefano Zampini if (nearnullsp) { 1553674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1554f4ddd8eeSStefano Zampini /* remove any stored info */ 1555f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1556f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1557f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 1558f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 1559f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 1560473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1561f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1562f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 1563f4ddd8eeSStefano Zampini } 1564984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 1565984c4197SStefano Zampini nnsp_size = 0; 1566674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 1567674ae819SStefano Zampini } 1568984c4197SStefano Zampini /* get max number of constraints on a single cc */ 1569984c4197SStefano Zampini max_constraints = nnsp_size; 1570984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 1571984c4197SStefano Zampini 1572674ae819SStefano Zampini /* 1573674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 1574674ae819SStefano Zampini - temp_indices will contain start index of each constraint stored as follows 1575911cabfeSStefano 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 1576911cabfeSStefano 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 1577911cabfeSStefano Zampini - temp_quadrature_constraint [temp_indices[i],...,temp_indices[i+1]-1] will contain the scalars representing the constraint itself 1578674ae819SStefano Zampini */ 1579674ae819SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 1580984c4197SStefano Zampini total_counts *= max_constraints; 1581674ae819SStefano Zampini n_vertices = 0; 1582674ae819SStefano Zampini if (ISForVertices) { 1583674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 1584674ae819SStefano Zampini } 1585674ae819SStefano Zampini total_counts += n_vertices; 1586854ce69bSBarry Smith ierr = PetscMalloc1(total_counts+1,&temp_indices);CHKERRQ(ierr); 15874641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 1588674ae819SStefano Zampini total_counts = 0; 1589674ae819SStefano Zampini max_size_of_constraint = 0; 1590674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 1591674ae819SStefano Zampini if (i<n_ISForEdges) { 1592674ae819SStefano Zampini used_IS = &ISForEdges[i]; 1593674ae819SStefano Zampini } else { 1594674ae819SStefano Zampini used_IS = &ISForFaces[i-n_ISForEdges]; 1595674ae819SStefano Zampini } 1596674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 1597674ae819SStefano Zampini total_counts += j; 1598674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 1599674ae819SStefano Zampini } 1600984c4197SStefano Zampini total_counts *= max_constraints; 1601674ae819SStefano Zampini total_counts += n_vertices; 1602906d46d4SStefano Zampini ierr = PetscMalloc3(total_counts,&temp_quadrature_constraint,total_counts,&temp_indices_to_constraint,total_counts,&temp_indices_to_constraint_B);CHKERRQ(ierr); 1603984c4197SStefano Zampini /* get local part of global near null space vectors */ 1604785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 1605984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 1606984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 1607984c4197SStefano Zampini ierr = VecScatterBegin(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1608984c4197SStefano Zampini ierr = VecScatterEnd(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1609984c4197SStefano Zampini } 1610674ae819SStefano Zampini 1611242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 1612242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 1613a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 1614242a89d7SStefano Zampini 16158f1c130eSStefano Zampini /* allocate some auxiliary stuff */ 16168f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 16178f1c130eSStefano 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); 16188f1c130eSStefano Zampini } 16198f1c130eSStefano Zampini 1620984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 1621a773dcb8SStefano Zampini if (!skip_lapack) { 1622674ae819SStefano Zampini PetscScalar temp_work; 1623911cabfeSStefano Zampini 1624674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1625984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 1626785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 1627785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 1628785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 1629674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1630785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 1631674ae819SStefano Zampini #endif 1632674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1633c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 1634c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 1635674ae819SStefano Zampini lwork = -1; 1636674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1637674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1638c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 1639674ae819SStefano Zampini #else 1640c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 1641674ae819SStefano Zampini #endif 1642674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1643984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 1644674ae819SStefano Zampini #else /* on missing GESVD */ 1645674ae819SStefano Zampini /* SVD */ 1646674ae819SStefano Zampini PetscInt max_n,min_n; 1647674ae819SStefano Zampini max_n = max_size_of_constraint; 1648984c4197SStefano Zampini min_n = max_constraints; 1649984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 1650674ae819SStefano Zampini min_n = max_size_of_constraint; 1651984c4197SStefano Zampini max_n = max_constraints; 1652674ae819SStefano Zampini } 1653785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 1654674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1655785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 1656674ae819SStefano Zampini #endif 1657674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1658674ae819SStefano Zampini lwork = -1; 1659e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 1660e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 1661b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 1662674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1663674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1664e310c8b4SStefano 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)); 1665674ae819SStefano Zampini #else 1666e310c8b4SStefano 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)); 1667674ae819SStefano Zampini #endif 1668674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1669984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 1670984c4197SStefano Zampini #endif /* on missing GESVD */ 1671674ae819SStefano Zampini /* Allocate optimal workspace */ 1672674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 1673854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 1674674ae819SStefano Zampini } 1675674ae819SStefano Zampini /* Now we can loop on constraining sets */ 1676674ae819SStefano Zampini total_counts = 0; 1677674ae819SStefano Zampini temp_indices[0] = 0; 1678674ae819SStefano Zampini /* vertices */ 1679674ae819SStefano Zampini if (ISForVertices) { 1680674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1681674ae819SStefano Zampini if (nnsp_has_cnst) { /* consider all vertices */ 168239e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 1683674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1684674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1685674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1686674ae819SStefano Zampini total_counts++; 1687674ae819SStefano Zampini } 1688674ae819SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 1689984c4197SStefano Zampini PetscBool used_vertex; 1690674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1691674ae819SStefano Zampini used_vertex = PETSC_FALSE; 1692674ae819SStefano Zampini k = 0; 1693674ae819SStefano Zampini while (!used_vertex && k<nnsp_size) { 1694984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1695984c4197SStefano Zampini if (PetscAbsScalar(array[is_indices[i]])>0.0) { 1696674ae819SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1697674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1698674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1699674ae819SStefano Zampini total_counts++; 1700674ae819SStefano Zampini used_vertex = PETSC_TRUE; 1701674ae819SStefano Zampini } 1702984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1703674ae819SStefano Zampini k++; 1704674ae819SStefano Zampini } 1705674ae819SStefano Zampini } 1706674ae819SStefano Zampini } 1707674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1708674ae819SStefano Zampini n_vertices = total_counts; 1709674ae819SStefano Zampini } 1710984c4197SStefano Zampini 1711674ae819SStefano Zampini /* edges and faces */ 1712911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 1713911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 1714911cabfeSStefano Zampini used_IS = &ISForEdges[ncc]; 1715984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 1716674ae819SStefano Zampini } else { 1717911cabfeSStefano Zampini used_IS = &ISForFaces[ncc-n_ISForEdges]; 1718984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 1719674ae819SStefano Zampini } 1720674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 1721674ae819SStefano Zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 1722674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 1723674ae819SStefano Zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1724984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 1725984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 1726674ae819SStefano Zampini if (nnsp_has_cnst) { 17275b08dc53SStefano Zampini PetscScalar quad_value; 1728674ae819SStefano Zampini temp_constraints++; 1729a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 1730674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 1731a773dcb8SStefano Zampini } else { 1732a773dcb8SStefano Zampini quad_value = 1.0; 1733a773dcb8SStefano Zampini } 173439e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1735674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1736674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 1737674ae819SStefano Zampini } 1738911cabfeSStefano Zampini /* sort by global ordering if using lapack subroutines */ 17398f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1740911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 1741911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1742911cabfeSStefano Zampini permutation[j]=j; 1743911cabfeSStefano Zampini } 1744911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 1745911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1746911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 1747911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 1748911cabfeSStefano Zampini } 1749911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1750911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 1751911cabfeSStefano Zampini } 1752674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 1753674ae819SStefano Zampini total_counts++; 1754674ae819SStefano Zampini } 1755674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 1756984c4197SStefano Zampini PetscReal real_value; 1757984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 175839e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1759674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1760984c4197SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array[is_indices[j]]; 1761674ae819SStefano Zampini } 1762984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1763984c4197SStefano Zampini /* check if array is null on the connected component */ 1764e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 1765e310c8b4SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,&temp_quadrature_constraint[temp_indices[total_counts]],&Blas_one)); 17665b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 1767911cabfeSStefano Zampini /* sort by global ordering if using lapack subroutines */ 17688f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1769911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 1770911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1771911cabfeSStefano Zampini permutation[j]=j; 1772911cabfeSStefano Zampini } 1773911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 1774911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1775911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 1776911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 1777911cabfeSStefano Zampini } 1778911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1779911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 1780911cabfeSStefano Zampini } 1781674ae819SStefano Zampini temp_constraints++; 1782674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 1783674ae819SStefano Zampini total_counts++; 1784674ae819SStefano Zampini } 1785674ae819SStefano Zampini } 1786674ae819SStefano Zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 178745a1bb75SStefano Zampini valid_constraints = temp_constraints; 1788eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 1789a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 1790a773dcb8SStefano Zampini PetscScalar norm; 1791a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 1792a773dcb8SStefano 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)); 1793a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 1794a773dcb8SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one)); 1795a773dcb8SStefano Zampini } else { /* perform SVD */ 1796984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 1797674ae819SStefano Zampini 1798674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1799984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 1800984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 1801984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 1802984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 1803984c4197SStefano Zampini from that computed using LAPACKgesvd 1804984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 1805984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 1806984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 1807674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 1808e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 1809984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1810674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 1811674ae819SStefano Zampini for (k=0;k<j+1;k++) { 1812e310c8b4SStefano 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)); 1813674ae819SStefano Zampini } 1814674ae819SStefano Zampini } 1815e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 1816e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 1817e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 1818674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1819c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 1820674ae819SStefano Zampini #else 1821c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 1822674ae819SStefano Zampini #endif 1823674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1824984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 1825984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 1826674ae819SStefano Zampini j = 0; 1827984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 1828674ae819SStefano Zampini total_counts = total_counts-j; 182945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 1830e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 1831c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 1832c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 1833c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 1834c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 1835c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 1836c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 1837674ae819SStefano Zampini if (j<temp_constraints) { 1838984c4197SStefano Zampini PetscInt ii; 1839984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); 1840674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1841c4303822SStefano 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)); 1842674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1843984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 1844674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 1845984c4197SStefano 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]; 1846674ae819SStefano Zampini } 1847674ae819SStefano Zampini } 1848674ae819SStefano Zampini } 1849674ae819SStefano Zampini #else /* on missing GESVD */ 1850e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 1851e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 1852b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 1853674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1854674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1855e310c8b4SStefano 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)); 1856674ae819SStefano Zampini #else 1857e310c8b4SStefano 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)); 1858674ae819SStefano Zampini #endif 1859984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 1860674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1861984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 1862e310c8b4SStefano Zampini k = temp_constraints; 1863e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 1864674ae819SStefano Zampini j = 0; 1865e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 186645a1bb75SStefano Zampini valid_constraints = k-j; 1867911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 1868984c4197SStefano Zampini #endif /* on missing GESVD */ 1869674ae819SStefano Zampini } 1870a773dcb8SStefano Zampini } 187145a1bb75SStefano Zampini /* setting change_of_basis flag is safe now */ 187245a1bb75SStefano Zampini if (boolforchange) { 187345a1bb75SStefano Zampini for (j=0;j<valid_constraints;j++) { 187445a1bb75SStefano Zampini PetscBTSet(change_basis,total_counts-j-1); 187545a1bb75SStefano Zampini } 187645a1bb75SStefano Zampini } 1877674ae819SStefano Zampini } 1878674ae819SStefano Zampini /* free index sets of faces, edges and vertices */ 1879674ae819SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 1880674ae819SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 1881674ae819SStefano Zampini } 1882d06fc5fdSStefano Zampini if (n_ISForFaces) { 1883674ae819SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 1884d06fc5fdSStefano Zampini } 1885674ae819SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 1886674ae819SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 1887674ae819SStefano Zampini } 1888d06fc5fdSStefano Zampini if (n_ISForEdges) { 1889674ae819SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 1890d06fc5fdSStefano Zampini } 1891674ae819SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 189239e2fb2aSStefano Zampini /* map temp_indices_to_constraint in boundary numbering */ 18935e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,temp_indices[total_counts],temp_indices_to_constraint,&i,temp_indices_to_constraint_B);CHKERRQ(ierr); 189439e2fb2aSStefano Zampini if (i != temp_indices[total_counts]) { 189539e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",temp_indices[total_counts],i); 189639e2fb2aSStefano Zampini } 1897674ae819SStefano Zampini 1898984c4197SStefano Zampini /* free workspace */ 18998f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1900911cabfeSStefano Zampini ierr = PetscFree4(gidxs,permutation,temp_indices_to_constraint_work,temp_quadrature_constraint_work);CHKERRQ(ierr); 19018f1c130eSStefano Zampini } 19028f1c130eSStefano Zampini if (!skip_lapack) { 1903984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1904984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1905984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 1906984c4197SStefano Zampini #endif 1907984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 1908984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1909984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 1910984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 1911984c4197SStefano Zampini #endif 1912984c4197SStefano Zampini } 1913984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 1914984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 1915984c4197SStefano Zampini } 1916984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 1917984c4197SStefano Zampini 1918727cdba6SStefano Zampini /* set quantities in pcbddc data structure and store previous primal size */ 1919984c4197SStefano Zampini /* n_vertices defines the number of subdomain corners in the primal space */ 1920674ae819SStefano Zampini /* n_constraints defines the number of averages (they can be point primal dofs if change of basis is requested) */ 1921727cdba6SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 1922984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 1923674ae819SStefano Zampini pcbddc->n_vertices = n_vertices; 1924984c4197SStefano Zampini pcbddc->n_constraints = pcbddc->local_primal_size-pcbddc->n_vertices; 1925674ae819SStefano Zampini 1926674ae819SStefano Zampini /* Create constraint matrix */ 1927674ae819SStefano Zampini /* The constraint matrix is used to compute the l2g map of primal dofs */ 1928674ae819SStefano Zampini /* so we need to set it up properly either with or without change of basis */ 1929674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1930674ae819SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 1931984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 1932984c4197SStefano Zampini /* array to compute a local numbering of constraints : vertices first then constraints */ 1933785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_numbering);CHKERRQ(ierr); 1934984c4197SStefano Zampini /* array to select the proper local node (of minimum index with respect to global ordering) when changing the basis */ 1935984c4197SStefano 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 */ 1936785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_minloc);CHKERRQ(ierr); 1937984c4197SStefano Zampini /* auxiliary stuff for basis change */ 1938785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&global_indices);CHKERRQ(ierr); 19394641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&touched);CHKERRQ(ierr); 1940984c4197SStefano Zampini 1941984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 1942984c4197SStefano Zampini total_primal_vertices=0; 1943984c4197SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1944674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 1945984c4197SStefano Zampini if (size_of_constraint == 1) { 19464641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]]);CHKERRQ(ierr); 1947984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]]; 1948984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=0; 1949984c4197SStefano Zampini total_primal_vertices++; 19504641a718SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { /* Same procedure used in PCBDDCGetPrimalConstraintsLocalIdx */ 1951984c4197SStefano Zampini PetscInt min_loc,min_index; 1952984c4197SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],global_indices);CHKERRQ(ierr); 1953984c4197SStefano Zampini /* find first untouched local node */ 1954674ae819SStefano Zampini k = 0; 19554641a718SStefano Zampini while (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) k++; 1956984c4197SStefano Zampini min_index = global_indices[k]; 1957984c4197SStefano Zampini min_loc = k; 1958984c4197SStefano Zampini /* search the minimum among global nodes already untouched on the cc */ 1959984c4197SStefano Zampini for (k=1;k<size_of_constraint;k++) { 1960984c4197SStefano Zampini /* there can be more than one constraint on a single connected component */ 19614641a718SStefano Zampini if (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k]) && min_index > global_indices[k]) { 1962984c4197SStefano Zampini min_index = global_indices[k]; 1963984c4197SStefano Zampini min_loc = k; 1964674ae819SStefano Zampini } 1965674ae819SStefano Zampini } 19664641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]+min_loc]);CHKERRQ(ierr); 1967984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]+min_loc]; 1968984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=min_loc; 1969984c4197SStefano Zampini total_primal_vertices++; 1970984c4197SStefano Zampini } 1971984c4197SStefano Zampini } 1972a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 1973a717540cSStefano Zampini qr_needed = PETSC_FALSE; 1974a717540cSStefano Zampini ierr = PetscBTCreate(pcbddc->local_primal_size,&qr_needed_idx);CHKERRQ(ierr); 1975a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 1976a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 1977fa434743SStefano Zampini if (!pcbddc->use_qr_single) { 1978a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 1979a717540cSStefano Zampini j = 0; 1980a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 1981a717540cSStefano Zampini if (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) { 1982a717540cSStefano Zampini j++; 1983a717540cSStefano Zampini } 1984a717540cSStefano Zampini } 1985a717540cSStefano Zampini /* found more than one primal dof on the cc */ 1986a717540cSStefano Zampini if (j > 1) { 1987a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 1988a717540cSStefano Zampini qr_needed = PETSC_TRUE; 1989a717540cSStefano Zampini } 1990fa434743SStefano Zampini } else { 1991fa434743SStefano Zampini PetscBTSet(qr_needed_idx,i); 1992fa434743SStefano Zampini qr_needed = PETSC_TRUE; 1993fa434743SStefano Zampini } 1994a717540cSStefano Zampini } 1995a717540cSStefano Zampini } 1996984c4197SStefano Zampini /* free workspace */ 1997984c4197SStefano Zampini ierr = PetscFree(global_indices);CHKERRQ(ierr); 199845a1bb75SStefano Zampini 1999674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 2000a717540cSStefano Zampini ierr = PetscSortInt(total_primal_vertices,aux_primal_numbering);CHKERRQ(ierr); 2001984c4197SStefano Zampini 2002984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 2003785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2004984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i]=1; 2005984c4197SStefano Zampini j=total_primal_vertices; 2006984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 20074641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2008674ae819SStefano Zampini nnz[j]=temp_indices[i+1]-temp_indices[i]; 2009674ae819SStefano Zampini j++; 2010674ae819SStefano Zampini } 2011674ae819SStefano Zampini } 2012674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2013674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2014674ae819SStefano Zampini /* set values in constraint matrix */ 2015984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 2016984c4197SStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,aux_primal_numbering[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2017674ae819SStefano Zampini } 2018984c4197SStefano Zampini total_counts = total_primal_vertices; 2019984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 20204641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2021674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2022674ae819SStefano 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); 2023674ae819SStefano Zampini total_counts++; 2024674ae819SStefano Zampini } 2025674ae819SStefano Zampini } 2026674ae819SStefano Zampini /* assembling */ 2027674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2028674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2029984c4197SStefano Zampini /* 203045a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2031984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2032984c4197SStefano Zampini */ 2033674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2034674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2035026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2036984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2037026de310SStefano Zampini /* iterator on aux_primal_minloc (ordered as read from nearnullspace: vertices, edges and then constraints) */ 2038026de310SStefano Zampini PetscInt primal_counter; 2039984c4197SStefano Zampini /* working stuff for GEQRF */ 204081d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2041984c4197SStefano Zampini PetscBLASInt lqr_work; 2042984c4197SStefano Zampini /* working stuff for UNGQR */ 2043984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2044984c4197SStefano Zampini PetscBLASInt lgqr_work; 2045984c4197SStefano Zampini /* working stuff for TRTRS */ 2046984c4197SStefano Zampini PetscScalar *trs_rhs; 20473f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2048984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2049984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2050984c4197SStefano Zampini PetscScalar *start_vals; 2051984c4197SStefano Zampini /* working stuff for values insertion */ 20524641a718SStefano Zampini PetscBT is_primal; 2053906d46d4SStefano Zampini /* matrix sizes */ 2054906d46d4SStefano Zampini PetscInt global_size,local_size; 2055906d46d4SStefano Zampini /* work array for nonzeros */ 2056906d46d4SStefano Zampini PetscScalar *nnz_array; 2057906d46d4SStefano Zampini /* temporary change of basis */ 2058906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2059906d46d4SStefano Zampini /* auxiliary work for global change of basis */ 2060906d46d4SStefano Zampini Vec nnz_vec; 206122bc73bbSStefano Zampini PetscInt *idxs_I,*idxs_B,*idxs_all,*d_nnz,*o_nnz; 2062906d46d4SStefano Zampini PetscInt nvtxs,*xadj,*adjncy,*idxs_mapped; 2063906d46d4SStefano Zampini PetscScalar *vals; 2064906d46d4SStefano Zampini PetscBool done; 2065984c4197SStefano Zampini 2066906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2067906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 2068906d46d4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,impMatType);CHKERRQ(ierr); 2069906d46d4SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n_B,pcis->n_B,pcis->n_B,pcis->n_B);CHKERRQ(ierr); 2070906d46d4SStefano Zampini 2071906d46d4SStefano Zampini /* nonzeros for local mat */ 2072785e854fSJed Brown ierr = PetscMalloc1(pcis->n_B,&nnz);CHKERRQ(ierr); 2073a717540cSStefano Zampini for (i=0;i<pcis->n_B;i++) nnz[i]=1; 2074a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 2075a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 2076a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2077a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 2078a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint_B[temp_indices[i]+j]] = size_of_constraint; 2079a717540cSStefano Zampini } else { 2080a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint_B[temp_indices[i]+j]] = 2; 2081a717540cSStefano Zampini /* get local primal index on the cc */ 2082a717540cSStefano Zampini j = 0; 2083a717540cSStefano Zampini while (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+j])) j++; 2084a717540cSStefano Zampini nnz[temp_indices_to_constraint_B[temp_indices[i]+j]] = size_of_constraint; 2085a717540cSStefano Zampini } 2086a717540cSStefano Zampini } 2087a717540cSStefano Zampini } 2088906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2089a717540cSStefano Zampini /* Set initial identity in the matrix */ 2090a717540cSStefano Zampini for (i=0;i<pcis->n_B;i++) { 2091906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 2092a717540cSStefano Zampini } 2093a717540cSStefano Zampini 2094a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2095a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2096a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2097a717540cSStefano Zampini } 2098a717540cSStefano Zampini 2099a717540cSStefano Zampini 2100a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 2101a717540cSStefano Zampini /* 2102a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 2103a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 2104a717540cSStefano Zampini 2105a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 2106a717540cSStefano Zampini 2107a6b551f4SStefano 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) 2108a6b551f4SStefano Zampini 2109a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 2110a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 2111a717540cSStefano Zampini | ... | 2112a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 2113a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 2114a717540cSStefano Zampini 2115a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 2116a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 2117a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 2118a6b551f4SStefano Zampini 2119a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 2120a717540cSStefano Zampini */ 2121a717540cSStefano Zampini if (qr_needed) { 2122984c4197SStefano Zampini /* space to store Q */ 2123854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 2124984c4197SStefano Zampini /* first we issue queries for optimal work */ 21253f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 21263f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 21273f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2128984c4197SStefano Zampini lqr_work = -1; 21293f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 2130984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 2131984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 2132785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 2133984c4197SStefano Zampini lgqr_work = -1; 21343f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 21353f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 21363f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 21373f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 21383f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 21393f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 2140984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 2141984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 2142785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 2143984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 2144785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 2145984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 2146785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 2147a717540cSStefano Zampini /* allocating workspace for check */ 2148a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2149785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&work);CHKERRQ(ierr); 2150a717540cSStefano Zampini } 2151a717540cSStefano Zampini } 2152984c4197SStefano Zampini /* array to store whether a node is primal or not */ 21534641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 2154473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 21555e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,aux_primal_numbering,&i,aux_primal_numbering_B);CHKERRQ(ierr); 215639e2fb2aSStefano Zampini if (i != total_primal_vertices) { 215739e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 21584641a718SStefano Zampini } 215939e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 216039e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 216139e2fb2aSStefano Zampini } 216239e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 2163984c4197SStefano Zampini 2164a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 2165026de310SStefano Zampini /* -> using implicit ordering contained in temp_indices data */ 2166026de310SStefano Zampini total_counts = pcbddc->n_vertices; 2167026de310SStefano Zampini primal_counter = total_counts; 2168026de310SStefano Zampini while (total_counts<pcbddc->local_primal_size) { 2169026de310SStefano Zampini primal_dofs = 1; 21704641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 2171026de310SStefano Zampini /* get all constraints with same support: if more then one constraint is present on the cc then surely indices are stored contiguosly */ 2172026de310SStefano 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]]) { 2173026de310SStefano Zampini primal_dofs++; 2174674ae819SStefano Zampini } 2175984c4197SStefano Zampini /* get constraint info */ 2176026de310SStefano Zampini size_of_constraint = temp_indices[total_counts+1]-temp_indices[total_counts]; 2177984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 2178984c4197SStefano Zampini 2179984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2180a717540cSStefano 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); 2181674ae819SStefano Zampini } 2182984c4197SStefano Zampini 2183fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 2184a717540cSStefano Zampini 2185a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 2186a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2187a717540cSStefano Zampini ierr = PetscMemcpy(work,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2188a717540cSStefano Zampini } 2189984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 2190026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2191984c4197SStefano Zampini 2192984c4197SStefano Zampini /* compute QR decomposition of constraints */ 21933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 21943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 21953f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2196674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 21973f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 2198984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 2199674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2200984c4197SStefano Zampini 2201984c4197SStefano Zampini /* explictly compute R^-T */ 2202984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 2203984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 22043f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 22053f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 22063f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 22073f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 2208984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 22093f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 2210984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 2211984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2212984c4197SStefano Zampini 2213a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 22143f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 22153f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 22163f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 22173f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2218984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 22193f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 2220984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 2221984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2222984c4197SStefano Zampini 2223984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 2224984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 2225984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 22263f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 22273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 22283f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 22293f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 22303f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 22313f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2232984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2233c4303822SStefano 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)); 2234984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2235026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2236984c4197SStefano Zampini 2237984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 2238026de310SStefano Zampini start_rows = &temp_indices_to_constraint_B[temp_indices[total_counts]]; 2239984c4197SStefano Zampini /* insert cols for primal dofs */ 2240984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 2241984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 2242026de310SStefano Zampini start_cols = &temp_indices_to_constraint_B[temp_indices[total_counts]+aux_primal_minloc[primal_counter+j]]; 2243906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2244984c4197SStefano Zampini } 2245984c4197SStefano Zampini /* insert cols for dual dofs */ 2246984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 22474641a718SStefano Zampini if (!PetscBTLookup(is_primal,temp_indices_to_constraint_B[temp_indices[total_counts]+k])) { 2248984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 2249026de310SStefano Zampini start_cols = &temp_indices_to_constraint_B[temp_indices[total_counts]+k]; 2250906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2251984c4197SStefano Zampini j++; 2252674ae819SStefano Zampini } 2253674ae819SStefano Zampini } 2254984c4197SStefano Zampini 2255984c4197SStefano Zampini /* check change of basis */ 2256984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2257984c4197SStefano Zampini PetscInt ii,jj; 2258984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 2259c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 2260c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2261c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 2262c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2263c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 2264c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 2265984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2266c4303822SStefano 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)); 2267984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2268984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2269984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2270984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 2271984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 2272674ae819SStefano Zampini } 2273674ae819SStefano Zampini } 2274984c4197SStefano Zampini if (!valid_qr) { 227522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 2276984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2277984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2278984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 2279984c4197SStefano 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])); 2280674ae819SStefano Zampini } 2281984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 2282984c4197SStefano 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])); 2283984c4197SStefano Zampini } 2284984c4197SStefano Zampini } 2285984c4197SStefano Zampini } 2286674ae819SStefano Zampini } else { 228722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 2288674ae819SStefano Zampini } 2289674ae819SStefano Zampini } 2290a717540cSStefano Zampini } else { /* simple transformation block */ 2291a717540cSStefano Zampini PetscInt row,col; 2292a6b551f4SStefano Zampini PetscScalar val,norm; 2293a6b551f4SStefano Zampini 2294a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2295a6b551f4SStefano 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)); 2296a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2297a717540cSStefano Zampini row = temp_indices_to_constraint_B[temp_indices[total_counts]+j]; 2298a717540cSStefano Zampini if (!PetscBTLookup(is_primal,row)) { 2299a717540cSStefano Zampini col = temp_indices_to_constraint_B[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2300906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 2301a6b551f4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,temp_quadrature_constraint[temp_indices[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 2302a717540cSStefano Zampini } else { 2303a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 2304a717540cSStefano Zampini col = temp_indices_to_constraint_B[temp_indices[total_counts]+k]; 2305a717540cSStefano Zampini if (row != col) { 2306a717540cSStefano Zampini val = -temp_quadrature_constraint[temp_indices[total_counts]+k]/temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2307a717540cSStefano Zampini } else { 2308a6b551f4SStefano Zampini val = temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]/norm; 2309a717540cSStefano Zampini } 2310906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 2311a717540cSStefano Zampini } 2312a717540cSStefano Zampini } 2313a717540cSStefano Zampini } 231498a51de6SStefano Zampini if (pcbddc->dbg_flag) { 231522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 2316a717540cSStefano Zampini } 2317674ae819SStefano Zampini } 2318026de310SStefano Zampini /* increment primal counter */ 2319026de310SStefano Zampini primal_counter += primal_dofs; 2320984c4197SStefano Zampini } else { 2321984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2322026de310SStefano 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); 2323674ae819SStefano Zampini } 2324674ae819SStefano Zampini } 2325026de310SStefano Zampini /* increment constraint counter total_counts */ 2326026de310SStefano Zampini total_counts += primal_dofs; 2327674ae819SStefano Zampini } 2328a717540cSStefano Zampini 2329a717540cSStefano Zampini /* free workspace */ 2330a717540cSStefano Zampini if (qr_needed) { 2331984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2332984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2333984c4197SStefano Zampini } 2334984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 2335984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 2336984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 2337984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 2338984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 2339674ae819SStefano Zampini } 2340a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 2341906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2342906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2343906d46d4SStefano Zampini 2344906d46d4SStefano Zampini /* assembling of global change of variable */ 2345906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2346906d46d4SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2347906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2348906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2349906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2350906d46d4SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->ChangeOfBasisMatrix,matis->mapping,matis->mapping);CHKERRQ(ierr); 2351906d46d4SStefano Zampini 2352906d46d4SStefano Zampini /* nonzeros (overestimated) */ 2353906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&nnz_vec);CHKERRQ(ierr); 2354906d46d4SStefano Zampini ierr = VecSetLocalToGlobalMapping(nnz_vec,matis->mapping);CHKERRQ(ierr); 2355906d46d4SStefano Zampini ierr = PetscMalloc2(pcis->n,&nnz_array,pcis->n,&idxs_all);CHKERRQ(ierr); 2356906d46d4SStefano Zampini for (i=0;i<pcis->n;i++) { 2357906d46d4SStefano Zampini nnz_array[i] = 1.0; 2358906d46d4SStefano Zampini idxs_all[i] = i; 2359906d46d4SStefano Zampini } 2360906d46d4SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&idxs_B);CHKERRQ(ierr); 2361906d46d4SStefano Zampini for (i=0;i<pcis->n_B;i++) { 2362906d46d4SStefano Zampini nnz_array[idxs_B[i]] = nnz[i]; 2363906d46d4SStefano Zampini } 2364a5187659SStefano Zampini if (pcis->n) { 2365906d46d4SStefano Zampini ierr = VecSetValuesLocal(nnz_vec,pcis->n,idxs_all,nnz_array,INSERT_VALUES);CHKERRQ(ierr); 2366a5187659SStefano Zampini } 2367906d46d4SStefano Zampini ierr = VecAssemblyBegin(nnz_vec);CHKERRQ(ierr); 2368906d46d4SStefano Zampini ierr = VecAssemblyEnd(nnz_vec);CHKERRQ(ierr); 2369906d46d4SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2370906d46d4SStefano Zampini ierr = PetscFree2(nnz_array,idxs_all);CHKERRQ(ierr); 237122bc73bbSStefano Zampini ierr = PetscMalloc2(local_size,&d_nnz,local_size,&o_nnz);CHKERRQ(ierr); 2372906d46d4SStefano Zampini ierr = VecGetArray(nnz_vec,&nnz_array);CHKERRQ(ierr); 2373906d46d4SStefano Zampini for (i=0;i<local_size;i++) { 237422bc73bbSStefano Zampini d_nnz[i] = PetscMin((PetscInt)(PetscRealPart(nnz_array[i])),local_size); 237522bc73bbSStefano Zampini o_nnz[i] = PetscMin((PetscInt)(PetscRealPart(nnz_array[i])),global_size-local_size); 2376906d46d4SStefano Zampini } 2377906d46d4SStefano Zampini ierr = VecRestoreArray(nnz_vec,&nnz_array);CHKERRQ(ierr); 2378906d46d4SStefano Zampini ierr = VecDestroy(&nnz_vec);CHKERRQ(ierr); 237922bc73bbSStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->ChangeOfBasisMatrix,0,d_nnz,0,o_nnz);CHKERRQ(ierr); 238022bc73bbSStefano Zampini ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); 2381906d46d4SStefano Zampini 2382906d46d4SStefano Zampini /* Set identity on dirichlet dofs */ 2383906d46d4SStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&idxs_I);CHKERRQ(ierr); 2384906d46d4SStefano Zampini for (i=0;i<pcis->n-pcis->n_B;i++) { 2385906d46d4SStefano Zampini PetscScalar one=1.0; 2386906d46d4SStefano Zampini ierr = MatSetValuesLocal(pcbddc->ChangeOfBasisMatrix,1,idxs_I+i,1,idxs_I+i,&one,INSERT_VALUES);CHKERRQ(ierr); 2387906d46d4SStefano Zampini } 2388906d46d4SStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&idxs_I);CHKERRQ(ierr); 2389906d46d4SStefano Zampini 2390906d46d4SStefano Zampini /* Set values at interface dofs */ 2391906d46d4SStefano Zampini done = PETSC_TRUE; 2392906d46d4SStefano Zampini ierr = MatGetRowIJ(localChangeOfBasisMatrix,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2393906d46d4SStefano Zampini if (!done) { 2394906d46d4SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 2395906d46d4SStefano Zampini } 2396906d46d4SStefano Zampini ierr = MatSeqAIJGetArray(localChangeOfBasisMatrix,&vals);CHKERRQ(ierr); 2397906d46d4SStefano Zampini ierr = PetscMalloc1(xadj[nvtxs],&idxs_mapped);CHKERRQ(ierr); 23985e8657edSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->BtoNmap,xadj[nvtxs],adjncy,idxs_mapped);CHKERRQ(ierr); 2399906d46d4SStefano Zampini for (i=0;i<nvtxs;i++) { 2400906d46d4SStefano Zampini PetscInt row,*cols,ncols; 2401906d46d4SStefano Zampini PetscScalar *mat_vals; 2402906d46d4SStefano Zampini 2403906d46d4SStefano Zampini row = idxs_B[i]; 2404906d46d4SStefano Zampini ncols = xadj[i+1]-xadj[i]; 2405906d46d4SStefano Zampini cols = idxs_mapped+xadj[i]; 2406906d46d4SStefano Zampini mat_vals = vals+xadj[i]; 2407906d46d4SStefano Zampini ierr = MatSetValuesLocal(pcbddc->ChangeOfBasisMatrix,1,&row,ncols,cols,mat_vals,INSERT_VALUES);CHKERRQ(ierr); 2408906d46d4SStefano Zampini } 2409906d46d4SStefano Zampini ierr = MatRestoreRowIJ(localChangeOfBasisMatrix,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2410906d46d4SStefano Zampini if (!done) { 2411906d46d4SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 2412906d46d4SStefano Zampini } 2413906d46d4SStefano Zampini ierr = MatSeqAIJRestoreArray(localChangeOfBasisMatrix,&vals);CHKERRQ(ierr); 2414906d46d4SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&idxs_B);CHKERRQ(ierr); 2415906d46d4SStefano Zampini ierr = PetscFree(idxs_mapped);CHKERRQ(ierr); 2416674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2417674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2418906d46d4SStefano Zampini 2419906d46d4SStefano Zampini /* check */ 2420906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2421906d46d4SStefano Zampini PetscReal error; 2422906d46d4SStefano Zampini Vec x,x_change; 2423906d46d4SStefano Zampini 2424906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 2425906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 2426906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2427906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 2428906d46d4SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2429906d46d4SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2430906d46d4SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 2431906d46d4SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2432906d46d4SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2433906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 2434906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2435906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2436906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2437906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on B: %1.6e\n",error);CHKERRQ(ierr); 2438906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2439906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2440906d46d4SStefano Zampini } 2441906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 2442906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 2443b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2444b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 2445b9b85e73SStefano Zampini } 2446906d46d4SStefano Zampini 2447906d46d4SStefano Zampini /* set up change of basis context */ 2448906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2449906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 2450906d46d4SStefano Zampini 2451906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 2452906d46d4SStefano Zampini PetscInt global_size,local_size; 2453906d46d4SStefano Zampini 2454906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2455906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2456906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 2457906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2458906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 2459906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 2460906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 2461906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 2462906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 2463906d46d4SStefano Zampini } else { 2464906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 2465906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 2466906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 2467906d46d4SStefano Zampini } 2468906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 2469906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2470906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 2471906d46d4SStefano Zampini } else { 2472906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2473906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 2474906d46d4SStefano Zampini } 2475906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 2476906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 2477906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2478906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2479b9b85e73SStefano Zampini } 2480a717540cSStefano Zampini 2481727cdba6SStefano Zampini /* get indices in local ordering for vertices and constraints */ 2482727cdba6SStefano 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 */ 2483473ba861SJed Brown ierr = PetscMalloc1(olocal_primal_size,&oprimal_indices_local_idxs);CHKERRQ(ierr); 2484727cdba6SStefano Zampini ierr = PetscMemcpy(oprimal_indices_local_idxs,pcbddc->primal_indices_local_idxs,olocal_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 2485727cdba6SStefano Zampini } 2486727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2487f347579bSStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2488473ba861SJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2489727cdba6SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_primal_numbering);CHKERRQ(ierr); 2490727cdba6SStefano Zampini ierr = PetscMemcpy(pcbddc->primal_indices_local_idxs,aux_primal_numbering,i*sizeof(PetscInt));CHKERRQ(ierr); 2491727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2492727cdba6SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_primal_numbering);CHKERRQ(ierr); 2493727cdba6SStefano Zampini ierr = PetscMemcpy(&pcbddc->primal_indices_local_idxs[i],aux_primal_numbering,j*sizeof(PetscInt));CHKERRQ(ierr); 2494727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2495e9189074SStefano Zampini /* set quantities in PCBDDC data struct */ 2496e9189074SStefano Zampini pcbddc->n_actual_vertices = i; 2497727cdba6SStefano Zampini /* check if a new primal space has been introduced */ 2498727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 2499727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 2500727cdba6SStefano Zampini ierr = PetscMemcmp(pcbddc->primal_indices_local_idxs,oprimal_indices_local_idxs,olocal_primal_size,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 2501c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 2502727cdba6SStefano Zampini ierr = PetscFree(oprimal_indices_local_idxs);CHKERRQ(ierr); 2503727cdba6SStefano Zampini } 2504727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 2505727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2506727cdba6SStefano Zampini 2507a717540cSStefano Zampini /* flush dbg viewer */ 2508b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 2509b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2510b8ffe317SStefano Zampini } 2511a717540cSStefano Zampini 2512e310c8b4SStefano Zampini /* free workspace */ 2513a717540cSStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 2514a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 2515984c4197SStefano Zampini ierr = PetscFree(aux_primal_minloc);CHKERRQ(ierr); 25164641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 2517906d46d4SStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 2518906d46d4SStefano Zampini ierr = PetscFree3(temp_quadrature_constraint,temp_indices_to_constraint,temp_indices_to_constraint_B);CHKERRQ(ierr); 2519674ae819SStefano Zampini PetscFunctionReturn(0); 2520674ae819SStefano Zampini } 2521674ae819SStefano Zampini 2522674ae819SStefano Zampini #undef __FUNCT__ 2523674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 2524674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 2525674ae819SStefano Zampini { 2526674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2527674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2528674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 252963602bcaSStefano Zampini PetscInt ierr,i,vertex_size; 2530674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2531674ae819SStefano Zampini 2532674ae819SStefano Zampini PetscFunctionBegin; 25338e61c736SStefano Zampini /* Reset previously computed graph */ 25348e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 2535674ae819SStefano Zampini /* Init local Graph struct */ 2536674ae819SStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,matis->mapping);CHKERRQ(ierr); 2537674ae819SStefano Zampini 2538575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 2539575ad6abSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 2540575ad6abSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2541575ad6abSStefano Zampini } 25429577ea80SStefano Zampini 2543674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 25444d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 2545674ae819SStefano Zampini Mat mat_adj; 25464d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 25474d379d7bSStefano Zampini PetscInt nvtxs; 2548674ae819SStefano Zampini PetscBool flg_row=PETSC_TRUE; 2549674ae819SStefano Zampini 2550674ae819SStefano Zampini ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 25514d379d7bSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2552674ae819SStefano Zampini if (!flg_row) { 2553674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 2554674ae819SStefano Zampini } 25554d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 25564d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 25574d379d7bSStefano Zampini pcbddc->deluxe_compute_rowadj = PETSC_FALSE; 25584d379d7bSStefano Zampini } else { /* just compute subdomain's connected components */ 25594d379d7bSStefano Zampini IS is_dummy; 25604d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 25614d379d7bSStefano Zampini PetscInt j,sum; 25624d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 25634d379d7bSStefano Zampini const PetscInt *idxs; 25644d379d7bSStefano Zampini PCBDDCGraph graph; 25654d379d7bSStefano Zampini PetscBT is_on_boundary; 25664d379d7bSStefano Zampini 25674d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 25684d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 25694d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 25704d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 25714d379d7bSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy);CHKERRQ(ierr); 25724d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 25734d379d7bSStefano Zampini graph->xadj = xadj; 25744d379d7bSStefano Zampini graph->adjncy = adjncy; 25754d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 25764d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 25774d379d7bSStefano Zampini 25784d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 25794d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains\n",PetscGlobalRank,graph->ncc);CHKERRQ(ierr); 25804d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 25814d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 25824d379d7bSStefano Zampini } 25834d379d7bSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 25844d379d7bSStefano Zampini } 25854d379d7bSStefano Zampini 25864d379d7bSStefano Zampini ierr = PetscBTCreate(nvtxs,&is_on_boundary);CHKERRQ(ierr); 25874d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 25884d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 25894d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 25904d379d7bSStefano Zampini } 25914d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 25924d379d7bSStefano Zampini 25934d379d7bSStefano Zampini ierr = PetscCalloc1(nvtxs+1,&cxadj);CHKERRQ(ierr); 25944d379d7bSStefano Zampini sum = 0; 25954d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 25964d379d7bSStefano Zampini PetscInt sizecc = 0; 25974d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 25984d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 25994d379d7bSStefano Zampini sizecc++; 26004d379d7bSStefano Zampini } 26014d379d7bSStefano Zampini } 26024d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 26034d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 26044d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 26054d379d7bSStefano Zampini } 26064d379d7bSStefano Zampini } 26074d379d7bSStefano Zampini sum += sizecc*sizecc; 26084d379d7bSStefano Zampini } 26094d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 26104d379d7bSStefano Zampini sum = 0; 26114d379d7bSStefano Zampini for (i=0;i<nvtxs;i++) { 26124d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 26134d379d7bSStefano Zampini cxadj[i] = sum; 26144d379d7bSStefano Zampini sum += temp; 26154d379d7bSStefano Zampini } 26164d379d7bSStefano Zampini cxadj[nvtxs] = sum; 26174d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 26184d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 26194d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 26204d379d7bSStefano Zampini PetscInt k,sizecc = 0; 26214d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 26224d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 26234d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 26244d379d7bSStefano Zampini sizecc++; 26254d379d7bSStefano Zampini } 26264d379d7bSStefano Zampini } 26274d379d7bSStefano Zampini } 26284d379d7bSStefano Zampini } 26294d379d7bSStefano Zampini } 26304d379d7bSStefano Zampini if (nvtxs) { 26314d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 26324d379d7bSStefano Zampini } else { 26334d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 26344d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 26354d379d7bSStefano Zampini } 26364d379d7bSStefano Zampini graph->xadj = 0; 26374d379d7bSStefano Zampini graph->adjncy = 0; 26384d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 26394d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 26404d379d7bSStefano Zampini } 26414d379d7bSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2642674ae819SStefano Zampini if (!flg_row) { 2643674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 2644674ae819SStefano Zampini } 2645674ae819SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2646674ae819SStefano Zampini } 2647674ae819SStefano Zampini 264863602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 2649674ae819SStefano Zampini vertex_size = 1; 265063602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 265163602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 265295ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 265363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 2654a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 265563602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2656674ae819SStefano Zampini } 265763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 265863602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 265963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 2660674ae819SStefano Zampini } 266163602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 2662674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 266363602bcaSStefano Zampini } else { 266463602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 266563602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 2666854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 266763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 266863602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 266963602bcaSStefano Zampini } 267063602bcaSStefano Zampini } 2671674ae819SStefano Zampini } 2672674ae819SStefano Zampini 2673674ae819SStefano Zampini /* Setup of Graph */ 2674785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 2675a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 2676785d1243SStefano Zampini } 2677785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 2678a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2679785d1243SStefano Zampini } 268063602bcaSStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices); 2681674ae819SStefano Zampini 2682674ae819SStefano Zampini /* Graph's connected components analysis */ 2683674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 2684674ae819SStefano Zampini 2685674ae819SStefano Zampini /* print some info to stdout */ 2686674ae819SStefano Zampini if (pcbddc->dbg_flag) { 2687e49050b4SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer); 2688674ae819SStefano Zampini } 2689fb180af4SStefano Zampini 2690fb180af4SStefano Zampini /* mark topography has done */ 2691fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 2692674ae819SStefano Zampini PetscFunctionReturn(0); 2693674ae819SStefano Zampini } 2694674ae819SStefano Zampini 2695674ae819SStefano Zampini #undef __FUNCT__ 2696674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalVerticesLocalIdx" 2697f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIdx(PC pc, PetscInt *n_vertices, PetscInt **vertices_idx) 2698674ae819SStefano Zampini { 2699674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2700674ae819SStefano Zampini PetscInt *vertices,*row_cmat_indices,n,i,size_of_constraint,local_primal_size; 2701674ae819SStefano Zampini PetscErrorCode ierr; 2702674ae819SStefano Zampini 2703674ae819SStefano Zampini PetscFunctionBegin; 2704674ae819SStefano Zampini n = 0; 2705674ae819SStefano Zampini vertices = 0; 2706674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 2707674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&i);CHKERRQ(ierr); 2708b120a5c6SStefano Zampini for (i=0;i<local_primal_size;i++) { 2709b120a5c6SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2710b120a5c6SStefano Zampini if (size_of_constraint == 1) n++; 2711b120a5c6SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2712b120a5c6SStefano Zampini } 2713811e8ca2SStefano Zampini if (vertices_idx) { 2714785e854fSJed Brown ierr = PetscMalloc1(n,&vertices);CHKERRQ(ierr); 2715b120a5c6SStefano Zampini n = 0; 2716674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2717674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2718674ae819SStefano Zampini if (size_of_constraint == 1) { 2719674ae819SStefano Zampini vertices[n++]=row_cmat_indices[0]; 2720674ae819SStefano Zampini } 2721674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2722674ae819SStefano Zampini } 2723674ae819SStefano Zampini } 2724811e8ca2SStefano Zampini } 2725674ae819SStefano Zampini *n_vertices = n; 2726811e8ca2SStefano Zampini if (vertices_idx) *vertices_idx = vertices; 2727674ae819SStefano Zampini PetscFunctionReturn(0); 2728674ae819SStefano Zampini } 2729674ae819SStefano Zampini 2730674ae819SStefano Zampini #undef __FUNCT__ 2731674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalConstraintsLocalIdx" 2732f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalConstraintsLocalIdx(PC pc, PetscInt *n_constraints, PetscInt **constraints_idx) 2733674ae819SStefano Zampini { 2734674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2735674ae819SStefano Zampini PetscInt *constraints_index,*row_cmat_indices,*row_cmat_global_indices; 2736674ae819SStefano Zampini PetscInt n,i,j,size_of_constraint,local_primal_size,local_size,max_size_of_constraint,min_index,min_loc; 27374641a718SStefano Zampini PetscBT touched; 2738674ae819SStefano Zampini PetscErrorCode ierr; 2739674ae819SStefano Zampini 2740f34684f1SStefano Zampini /* This function assumes that the number of local constraints per connected component 2741f34684f1SStefano Zampini is not greater than the number of nodes defined for the connected component 2742f34684f1SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 2743674ae819SStefano Zampini PetscFunctionBegin; 2744674ae819SStefano Zampini n = 0; 2745674ae819SStefano Zampini constraints_index = 0; 2746674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 2747674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&local_size);CHKERRQ(ierr); 2748674ae819SStefano Zampini max_size_of_constraint = 0; 2749674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2750674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2751674ae819SStefano Zampini if (size_of_constraint > 1) { 2752674ae819SStefano Zampini n++; 2753674ae819SStefano Zampini } 2754674ae819SStefano Zampini max_size_of_constraint = PetscMax(size_of_constraint,max_size_of_constraint); 2755674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2756674ae819SStefano Zampini } 2757811e8ca2SStefano Zampini if (constraints_idx) { 2758785e854fSJed Brown ierr = PetscMalloc1(n,&constraints_index);CHKERRQ(ierr); 2759785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&row_cmat_global_indices);CHKERRQ(ierr); 27604641a718SStefano Zampini ierr = PetscBTCreate(local_size,&touched);CHKERRQ(ierr); 2761674ae819SStefano Zampini n = 0; 2762674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2763674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2764674ae819SStefano Zampini if (size_of_constraint > 1) { 2765674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,row_cmat_indices,row_cmat_global_indices);CHKERRQ(ierr); 276682d3d8afSStefano Zampini /* find first untouched local node */ 276782d3d8afSStefano Zampini j = 0; 27684641a718SStefano Zampini while (PetscBTLookup(touched,row_cmat_indices[j])) j++; 276982d3d8afSStefano Zampini min_index = row_cmat_global_indices[j]; 277082d3d8afSStefano Zampini min_loc = j; 277182d3d8afSStefano Zampini /* search the minimum among nodes not yet touched on the connected component 277282d3d8afSStefano Zampini since there can be more than one constraint on a single cc */ 2773674ae819SStefano Zampini for (j=1;j<size_of_constraint;j++) { 27744641a718SStefano Zampini if (!PetscBTLookup(touched,row_cmat_indices[j]) && min_index > row_cmat_global_indices[j]) { 2775674ae819SStefano Zampini min_index = row_cmat_global_indices[j]; 2776674ae819SStefano Zampini min_loc = j; 2777674ae819SStefano Zampini } 2778674ae819SStefano Zampini } 27794641a718SStefano Zampini ierr = PetscBTSet(touched,row_cmat_indices[min_loc]);CHKERRQ(ierr); 2780674ae819SStefano Zampini constraints_index[n++] = row_cmat_indices[min_loc]; 2781674ae819SStefano Zampini } 2782674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2783674ae819SStefano Zampini } 27844641a718SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 2785674ae819SStefano Zampini ierr = PetscFree(row_cmat_global_indices);CHKERRQ(ierr); 2786811e8ca2SStefano Zampini } 2787811e8ca2SStefano Zampini } 2788674ae819SStefano Zampini *n_constraints = n; 2789811e8ca2SStefano Zampini if (constraints_idx) *constraints_idx = constraints_index; 2790674ae819SStefano Zampini PetscFunctionReturn(0); 2791674ae819SStefano Zampini } 2792674ae819SStefano Zampini 2793674ae819SStefano Zampini #undef __FUNCT__ 2794674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 2795674ae819SStefano 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[]) 2796674ae819SStefano Zampini { 2797674ae819SStefano Zampini Vec local_vec,global_vec; 2798674ae819SStefano Zampini IS seqis,paris; 2799674ae819SStefano Zampini VecScatter scatter_ctx; 2800674ae819SStefano Zampini PetscScalar *array; 2801674ae819SStefano Zampini PetscInt *temp_global_dofs; 2802674ae819SStefano Zampini PetscScalar globalsum; 2803674ae819SStefano Zampini PetscInt i,j,s; 2804674ae819SStefano Zampini PetscInt nlocals,first_index,old_index,max_local; 2805674ae819SStefano Zampini PetscMPIInt rank_prec_comm,size_prec_comm,max_global; 2806674ae819SStefano Zampini PetscMPIInt *dof_sizes,*dof_displs; 2807674ae819SStefano Zampini PetscBool first_found; 2808674ae819SStefano Zampini PetscErrorCode ierr; 2809674ae819SStefano Zampini 2810674ae819SStefano Zampini PetscFunctionBegin; 2811674ae819SStefano Zampini /* mpi buffers */ 2812b9b85e73SStefano Zampini ierr = MPI_Comm_size(comm,&size_prec_comm);CHKERRQ(ierr); 2813b9b85e73SStefano Zampini ierr = MPI_Comm_rank(comm,&rank_prec_comm);CHKERRQ(ierr); 2814674ae819SStefano Zampini j = ( !rank_prec_comm ? size_prec_comm : 0); 2815785e854fSJed Brown ierr = PetscMalloc1(j,&dof_sizes);CHKERRQ(ierr); 2816785e854fSJed Brown ierr = PetscMalloc1(j,&dof_displs);CHKERRQ(ierr); 2817674ae819SStefano Zampini /* get maximum size of subset */ 2818785e854fSJed Brown ierr = PetscMalloc1(n_local_dofs,&temp_global_dofs);CHKERRQ(ierr); 2819674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2gmap,n_local_dofs,local_dofs,temp_global_dofs);CHKERRQ(ierr); 2820674ae819SStefano Zampini max_local = 0; 2821b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2822674ae819SStefano Zampini if (max_local < temp_global_dofs[i] ) { 2823674ae819SStefano Zampini max_local = temp_global_dofs[i]; 2824674ae819SStefano Zampini } 2825674ae819SStefano Zampini } 2826b9b85e73SStefano Zampini ierr = MPI_Allreduce(&max_local,&max_global,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 2827674ae819SStefano Zampini max_global++; 2828674ae819SStefano Zampini max_local = 0; 2829b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2830674ae819SStefano Zampini if (max_local < local_dofs[i] ) { 2831674ae819SStefano Zampini max_local = local_dofs[i]; 2832674ae819SStefano Zampini } 2833674ae819SStefano Zampini } 2834674ae819SStefano Zampini max_local++; 2835674ae819SStefano Zampini /* allocate workspace */ 2836674ae819SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&local_vec);CHKERRQ(ierr); 2837674ae819SStefano Zampini ierr = VecSetSizes(local_vec,PETSC_DECIDE,max_local);CHKERRQ(ierr); 2838674ae819SStefano Zampini ierr = VecSetType(local_vec,VECSEQ);CHKERRQ(ierr); 2839674ae819SStefano Zampini ierr = VecCreate(comm,&global_vec);CHKERRQ(ierr); 2840674ae819SStefano Zampini ierr = VecSetSizes(global_vec,PETSC_DECIDE,max_global);CHKERRQ(ierr); 2841674ae819SStefano Zampini ierr = VecSetType(global_vec,VECMPI);CHKERRQ(ierr); 2842674ae819SStefano Zampini /* create scatter */ 2843674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_local_dofs,local_dofs,PETSC_COPY_VALUES,&seqis);CHKERRQ(ierr); 2844674ae819SStefano Zampini ierr = ISCreateGeneral(comm,n_local_dofs,temp_global_dofs,PETSC_COPY_VALUES,&paris);CHKERRQ(ierr); 2845674ae819SStefano Zampini ierr = VecScatterCreate(local_vec,seqis,global_vec,paris,&scatter_ctx);CHKERRQ(ierr); 2846674ae819SStefano Zampini ierr = ISDestroy(&seqis);CHKERRQ(ierr); 2847674ae819SStefano Zampini ierr = ISDestroy(&paris);CHKERRQ(ierr); 2848674ae819SStefano Zampini /* init array */ 2849674ae819SStefano Zampini ierr = VecSet(global_vec,0.0);CHKERRQ(ierr); 2850674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 2851674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 2852674ae819SStefano Zampini if (local_dofs_mult) { 2853674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2854674ae819SStefano Zampini array[local_dofs[i]]=(PetscScalar)local_dofs_mult[i]; 2855674ae819SStefano Zampini } 2856674ae819SStefano Zampini } else { 2857674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 2858674ae819SStefano Zampini array[local_dofs[i]]=1.0; 2859674ae819SStefano Zampini } 2860674ae819SStefano Zampini } 2861674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 2862674ae819SStefano Zampini /* scatter into global vec and get total number of global dofs */ 2863674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2864674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2865674ae819SStefano Zampini ierr = VecSum(global_vec,&globalsum);CHKERRQ(ierr); 28665b08dc53SStefano Zampini *n_global_subset = (PetscInt)PetscRealPart(globalsum); 2867674ae819SStefano Zampini /* Fill global_vec with cumulative function for global numbering */ 2868674ae819SStefano Zampini ierr = VecGetArray(global_vec,&array);CHKERRQ(ierr); 2869674ae819SStefano Zampini ierr = VecGetLocalSize(global_vec,&s);CHKERRQ(ierr); 2870674ae819SStefano Zampini nlocals = 0; 2871674ae819SStefano Zampini first_index = -1; 2872674ae819SStefano Zampini first_found = PETSC_FALSE; 2873674ae819SStefano Zampini for (i=0;i<s;i++) { 2874b9b85e73SStefano Zampini if (!first_found && PetscRealPart(array[i]) > 0.1) { 2875674ae819SStefano Zampini first_found = PETSC_TRUE; 2876674ae819SStefano Zampini first_index = i; 2877674ae819SStefano Zampini } 28785b08dc53SStefano Zampini nlocals += (PetscInt)PetscRealPart(array[i]); 2879674ae819SStefano Zampini } 2880674ae819SStefano Zampini ierr = MPI_Gather(&nlocals,1,MPIU_INT,dof_sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 2881674ae819SStefano Zampini if (!rank_prec_comm) { 2882674ae819SStefano Zampini dof_displs[0]=0; 2883674ae819SStefano Zampini for (i=1;i<size_prec_comm;i++) { 2884674ae819SStefano Zampini dof_displs[i] = dof_displs[i-1]+dof_sizes[i-1]; 2885674ae819SStefano Zampini } 2886674ae819SStefano Zampini } 2887674ae819SStefano Zampini ierr = MPI_Scatter(dof_displs,1,MPIU_INT,&nlocals,1,MPIU_INT,0,comm);CHKERRQ(ierr); 2888674ae819SStefano Zampini if (first_found) { 2889674ae819SStefano Zampini array[first_index] += (PetscScalar)nlocals; 2890674ae819SStefano Zampini old_index = first_index; 2891674ae819SStefano Zampini for (i=first_index+1;i<s;i++) { 2892b9b85e73SStefano Zampini if (PetscRealPart(array[i]) > 0.1) { 2893674ae819SStefano Zampini array[i] += array[old_index]; 2894674ae819SStefano Zampini old_index = i; 2895674ae819SStefano Zampini } 2896674ae819SStefano Zampini } 2897674ae819SStefano Zampini } 2898674ae819SStefano Zampini ierr = VecRestoreArray(global_vec,&array);CHKERRQ(ierr); 2899674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 2900674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2901674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2902674ae819SStefano Zampini /* get global ordering of local dofs */ 2903674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 2904674ae819SStefano Zampini if (local_dofs_mult) { 2905674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 29065b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-local_dofs_mult[i]; 2907674ae819SStefano Zampini } 2908674ae819SStefano Zampini } else { 2909674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 29105b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-1; 2911674ae819SStefano Zampini } 2912674ae819SStefano Zampini } 2913674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 2914674ae819SStefano Zampini /* free workspace */ 2915674ae819SStefano Zampini ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); 2916674ae819SStefano Zampini ierr = VecDestroy(&local_vec);CHKERRQ(ierr); 2917674ae819SStefano Zampini ierr = VecDestroy(&global_vec);CHKERRQ(ierr); 2918674ae819SStefano Zampini ierr = PetscFree(dof_sizes);CHKERRQ(ierr); 2919674ae819SStefano Zampini ierr = PetscFree(dof_displs);CHKERRQ(ierr); 2920674ae819SStefano Zampini /* return pointer to global ordering of local dofs */ 2921674ae819SStefano Zampini *global_numbering_subset = temp_global_dofs; 2922674ae819SStefano Zampini PetscFunctionReturn(0); 2923674ae819SStefano Zampini } 29249a7d3425SStefano Zampini 29259a7d3425SStefano Zampini #undef __FUNCT__ 29269a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 29279a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 29289a7d3425SStefano Zampini { 29299a7d3425SStefano Zampini PetscInt i,j; 29309a7d3425SStefano Zampini PetscScalar *alphas; 29319a7d3425SStefano Zampini PetscErrorCode ierr; 29329a7d3425SStefano Zampini 29339a7d3425SStefano Zampini PetscFunctionBegin; 29349a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 2935785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 29369a7d3425SStefano Zampini for (i=0;i<n;i++) { 29379a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 29389a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 29399a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 29409a7d3425SStefano Zampini } 29419a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 29429a7d3425SStefano Zampini PetscFunctionReturn(0); 29439a7d3425SStefano Zampini } 29449a7d3425SStefano Zampini 2945e7931f94SStefano Zampini #undef __FUNCT__ 294670cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 294728143c3dSStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscBool contiguous, IS* is_sends) 2948e7931f94SStefano Zampini { 2949e7931f94SStefano Zampini Mat subdomain_adj; 2950e7931f94SStefano Zampini IS new_ranks,ranks_send_to; 2951e7931f94SStefano Zampini MatPartitioning partitioner; 2952e7931f94SStefano Zampini Mat_IS *matis; 2953e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 2954e7931f94SStefano Zampini PetscInt prank; 2955e7931f94SStefano Zampini PetscMPIInt size,rank,color; 2956e7931f94SStefano Zampini PetscInt *xadj,*adjncy,*oldranks; 2957e7931f94SStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*is_indices,*ranks_send_to_idx; 29583837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 2959e7931f94SStefano Zampini PetscErrorCode ierr; 29602b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 2961e7931f94SStefano Zampini PetscSubcomm subcomm; 2962a57a6d2fSStefano Zampini 2963e7931f94SStefano Zampini PetscFunctionBegin; 29642b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 29652b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 29662b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 2967e7931f94SStefano Zampini 2968e7931f94SStefano Zampini /* Get info on mapping */ 2969e7931f94SStefano Zampini matis = (Mat_IS*)(mat->data); 2970e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&local_size);CHKERRQ(ierr); 2971e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 2972e7931f94SStefano Zampini 2973e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 2974785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 2975e7931f94SStefano Zampini xadj[0] = 0; 2976e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 2977785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 2978785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 2979e7931f94SStefano Zampini 29802b510759SStefano Zampini if (threshold) { 2981d023bfaeSStefano Zampini PetscInt xadj_count = 0; 29822b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 2983d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 2984d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 2985d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 2986d023bfaeSStefano Zampini xadj_count++; 2987e7931f94SStefano Zampini } 2988e7931f94SStefano Zampini } 2989d023bfaeSStefano Zampini xadj[1] = xadj_count; 2990c8587f34SStefano Zampini } else { 2991e7931f94SStefano Zampini if (xadj[1]) { 2992e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 2993e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 2994c8587f34SStefano Zampini } 2995e7931f94SStefano Zampini } 2996e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 2997e7931f94SStefano Zampini if (use_square) { 2998e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 2999e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3000e7931f94SStefano Zampini } 3001e7931f94SStefano Zampini } 3002e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3003e7931f94SStefano Zampini 30043837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3005e7931f94SStefano Zampini 3006e7931f94SStefano Zampini /* 3007e7931f94SStefano Zampini Restrict work on active processes only. 3008e7931f94SStefano Zampini */ 3009e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3010e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3011e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 30122b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3013d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3014e7931f94SStefano Zampini if (color) { 3015e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3016e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3017e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3018c8587f34SStefano Zampini } else { 301928143c3dSStefano Zampini PetscInt coarsening_ratio; 3020e7931f94SStefano Zampini ierr = MPI_Comm_size(subcomm->comm,&size);CHKERRQ(ierr); 3021785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3022e7931f94SStefano Zampini prank = rank; 3023e7931f94SStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm->comm);CHKERRQ(ierr); 30248002ef2cSStefano Zampini /* 3025e7931f94SStefano Zampini for (i=0;i<size;i++) { 3026e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3027c8587f34SStefano Zampini } 30288002ef2cSStefano Zampini */ 3029e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3030e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3031c8587f34SStefano Zampini } 3032e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3033e7931f94SStefano Zampini ierr = MatCreateMPIAdj(subcomm->comm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 303422b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3035e7931f94SStefano Zampini 3036e7931f94SStefano Zampini /* Partition */ 3037e7931f94SStefano Zampini ierr = MatPartitioningCreate(subcomm->comm,&partitioner);CHKERRQ(ierr); 3038e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3039e7931f94SStefano Zampini if (use_vwgt) { 30403837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3041e7931f94SStefano Zampini v_wgt[0] = local_size; 3042e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3043c8587f34SStefano Zampini } 304428143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 304528143c3dSStefano Zampini coarsening_ratio = size/n_subdomains; 304628143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3047e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3048e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 304922b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3050e7931f94SStefano Zampini 3051e7931f94SStefano Zampini ierr = ISGetIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 305228143c3dSStefano Zampini if (contiguous) { 305328143c3dSStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; /* contiguos set of processes */ 305428143c3dSStefano Zampini } else { 305584ba6060SStefano Zampini ranks_send_to_idx[0] = coarsening_ratio*oldranks[is_indices[0]]; /* scattered set of processes */ 305628143c3dSStefano Zampini } 3057e7931f94SStefano Zampini ierr = ISRestoreIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3058e7931f94SStefano Zampini /* clean up */ 3059e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 3060e7931f94SStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 3061e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3062e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3063e7931f94SStefano Zampini } 3064e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3065e7931f94SStefano Zampini 3066e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3067e7931f94SStefano Zampini i = 1; 3068e7931f94SStefano Zampini if (color) i=0; 3069e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3070e7931f94SStefano Zampini 3071e7931f94SStefano Zampini /* get back IS */ 3072e7931f94SStefano Zampini *is_sends = ranks_send_to; 3073e7931f94SStefano Zampini PetscFunctionReturn(0); 3074e7931f94SStefano Zampini } 3075e7931f94SStefano Zampini 3076e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3077e7931f94SStefano Zampini 3078e7931f94SStefano Zampini #undef __FUNCT__ 3079e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 308028143c3dSStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 3081e7931f94SStefano Zampini { 308270cf5478SStefano Zampini Mat local_mat; 3083e7931f94SStefano Zampini Mat_IS *matis; 3084e7931f94SStefano Zampini IS is_sends_internal; 30859d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 308628143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 30879d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3088e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3089e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3090e7931f94SStefano Zampini const PetscInt* is_indices; 3091e7931f94SStefano Zampini MatType new_local_type; 3092e7931f94SStefano Zampini /* buffers */ 3093e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 309428143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 30959d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3096e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3097e7931f94SStefano Zampini /* MPI */ 309828143c3dSStefano Zampini MPI_Comm comm,comm_n; 309928143c3dSStefano Zampini PetscSubcomm subcomm; 3100e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 310128143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 310228143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 310328143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 310428143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 310528143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3106e7931f94SStefano Zampini PetscErrorCode ierr; 3107e7931f94SStefano Zampini 3108e7931f94SStefano Zampini PetscFunctionBegin; 310928143c3dSStefano Zampini /* TODO: add missing checks */ 311028143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 311128143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 311228143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 311328143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3114e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 311528143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3116e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3117e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3118e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3119e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3120e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 312128143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 312270cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 312370cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 312428143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 312570cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 312670cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 312770cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 312870cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 312970cf5478SStefano Zampini } 3130e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 3131e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 3132e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 3133e7931f94SStefano Zampini if (!is_sends) { 313428143c3dSStefano Zampini PetscBool pcontig = PETSC_TRUE; 313528143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 313628143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,pcontig,&is_sends_internal);CHKERRQ(ierr); 3137c8587f34SStefano Zampini } else { 3138e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 3139e7931f94SStefano Zampini is_sends_internal = is_sends; 3140c8587f34SStefano Zampini } 3141e7931f94SStefano Zampini 3142e7931f94SStefano Zampini /* get pointer of MATIS data */ 3143e7931f94SStefano Zampini matis = (Mat_IS*)mat->data; 3144e7931f94SStefano Zampini 3145e7931f94SStefano Zampini /* get comm */ 3146a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3147e7931f94SStefano Zampini 3148e7931f94SStefano Zampini /* compute number of sends */ 3149e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 3150e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 3151e7931f94SStefano Zampini 3152e7931f94SStefano Zampini /* compute number of receives */ 3153e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 3154785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 3155e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 3156e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3157e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 3158e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 3159e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 3160e7931f94SStefano Zampini 316128143c3dSStefano Zampini /* restrict comm if requested */ 316228143c3dSStefano Zampini subcomm = 0; 316328143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 316428143c3dSStefano Zampini if (restrict_comm) { 316528143c3dSStefano Zampini PetscMPIInt color,rank,subcommsize; 316628143c3dSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 316728143c3dSStefano Zampini color = 0; 316828143c3dSStefano Zampini if (n_sends && !n_recvs) color = 1; /* sending only processes will not partecipate in new comm */ 316928143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 317028143c3dSStefano Zampini subcommsize = commsize - subcommsize; 317128143c3dSStefano Zampini /* check if reuse has been requested */ 317228143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 317328143c3dSStefano Zampini if (*mat_n) { 317428143c3dSStefano Zampini PetscMPIInt subcommsize2; 317528143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 317628143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 317728143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 317828143c3dSStefano Zampini } else { 317928143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 318028143c3dSStefano Zampini } 318128143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 318228143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 318328143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 318428143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 318528143c3dSStefano Zampini comm_n = subcomm->comm; 318628143c3dSStefano Zampini } 318728143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 318828143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 318928143c3dSStefano Zampini } else { 319028143c3dSStefano Zampini comm_n = comm; 319128143c3dSStefano Zampini } 319228143c3dSStefano Zampini 3193e7931f94SStefano Zampini /* prepare send/receive buffers */ 3194785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 3195e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 3196785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 3197e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 319828143c3dSStefano Zampini if (nis) { 3199854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 320028143c3dSStefano Zampini } 3201e7931f94SStefano Zampini 320228143c3dSStefano Zampini /* Get data from local matrices */ 3203e7931f94SStefano Zampini if (!isdense) { 3204a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 3205e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 3206e7931f94SStefano Zampini /* 3207e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 3208e7931f94SStefano Zampini send_buffer_idxs should contain: 3209e7931f94SStefano Zampini - MatType_PRIVATE type 3210e7931f94SStefano Zampini - PetscInt size_of_l2gmap 3211e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 3212e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 3213e7931f94SStefano Zampini */ 3214e7931f94SStefano Zampini } else { 3215e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3216e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&i);CHKERRQ(ierr); 3217854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 3218e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 3219e7931f94SStefano Zampini send_buffer_idxs[1] = i; 3220e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3221e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 3222e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3223e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 3224e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3225e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 3226e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 3227c8587f34SStefano Zampini } 3228c8587f34SStefano Zampini } 3229e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 323028143c3dSStefano Zampini /* additional is (if any) */ 323128143c3dSStefano Zampini if (nis) { 323228143c3dSStefano Zampini PetscMPIInt psum; 323328143c3dSStefano Zampini PetscInt j; 323428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 323528143c3dSStefano Zampini PetscInt plen; 323628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 323728143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 323828143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 323928143c3dSStefano Zampini } 3240854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 324128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 324228143c3dSStefano Zampini PetscInt plen; 324328143c3dSStefano Zampini const PetscInt *is_array_idxs; 324428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 324528143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 324628143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 324728143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 324828143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 324928143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 325028143c3dSStefano Zampini } 325128143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 325228143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 325328143c3dSStefano Zampini } 325428143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 325528143c3dSStefano Zampini } 325628143c3dSStefano Zampini 3257e7931f94SStefano Zampini buf_size_idxs = 0; 3258e7931f94SStefano Zampini buf_size_vals = 0; 325928143c3dSStefano Zampini buf_size_idxs_is = 0; 3260e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3261e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 3262e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 326328143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 3264e7931f94SStefano Zampini } 3265785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 3266785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 326795ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 3268e7931f94SStefano Zampini 3269e7931f94SStefano Zampini /* get new tags for clean communications */ 3270e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 3271e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 327228143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 3273e7931f94SStefano Zampini 3274e7931f94SStefano Zampini /* allocate for requests */ 3275785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 3276785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 327795ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 3278785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 3279785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 328095ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 3281e7931f94SStefano Zampini 3282e7931f94SStefano Zampini /* communications */ 3283e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3284e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 328528143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 3286e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3287e7931f94SStefano Zampini source_dest = onodes[i]; 3288e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 3289e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 3290e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3291e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 329228143c3dSStefano Zampini if (nis) { 329328143c3dSStefano 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); 329428143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 329528143c3dSStefano Zampini } 3296e7931f94SStefano Zampini } 3297e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3298e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 3299e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 3300e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 330128143c3dSStefano Zampini if (nis) { 330228143c3dSStefano 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); 330328143c3dSStefano Zampini } 3304e7931f94SStefano Zampini } 3305e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3306e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 3307e7931f94SStefano Zampini 3308e7931f94SStefano Zampini /* assemble new l2g map */ 3309e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3310e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 33119d30be91SStefano Zampini new_local_rows = 0; 3312e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 33139d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3314e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3315e7931f94SStefano Zampini } 33169d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 3317e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 33189d30be91SStefano Zampini new_local_rows = 0; 3319e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 33209d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 33219d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3322e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3323e7931f94SStefano Zampini } 33249d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 33259d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 3326e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 3327e7931f94SStefano Zampini 3328e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 3329e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 3330e7931f94SStefano 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) */ 3331e7931f94SStefano Zampini if (n_recvs) { 333228143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 3333e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3334e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3335e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 3336e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 3337e7931f94SStefano Zampini break; 3338e7931f94SStefano Zampini } 3339e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3340e7931f94SStefano Zampini } 3341e7931f94SStefano Zampini switch (new_local_type_private) { 334228143c3dSStefano Zampini case MATDENSE_PRIVATE: 334328143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 3344e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3345e7931f94SStefano Zampini bs = 1; 334628143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 334728143c3dSStefano Zampini new_local_type = MATSEQDENSE; 334828143c3dSStefano Zampini bs = 1; 334928143c3dSStefano Zampini } 3350e7931f94SStefano Zampini break; 3351e7931f94SStefano Zampini case MATAIJ_PRIVATE: 3352e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3353e7931f94SStefano Zampini bs = 1; 3354e7931f94SStefano Zampini break; 3355e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 3356e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 3357e7931f94SStefano Zampini break; 3358e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 3359e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 3360e7931f94SStefano Zampini break; 3361e7931f94SStefano Zampini default: 33629d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 3363e7931f94SStefano Zampini break; 3364e7931f94SStefano Zampini } 336528143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 336628143c3dSStefano Zampini new_local_type = MATSEQDENSE; 336728143c3dSStefano Zampini bs = 1; 3368e7931f94SStefano Zampini } 3369e7931f94SStefano Zampini 337070cf5478SStefano Zampini /* create MATIS object if needed */ 337170cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 3372e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 337328143c3dSStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,mat_n);CHKERRQ(ierr); 337470cf5478SStefano Zampini } else { 337570cf5478SStefano Zampini /* it also destroys the local matrices */ 337670cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 337770cf5478SStefano Zampini } 337870cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 3379e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 33809d30be91SStefano Zampini 33819d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 33829d30be91SStefano Zampini 33839d30be91SStefano Zampini /* Global to local map of received indices */ 33849d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 33859d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 33869d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 33879d30be91SStefano Zampini 33889d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 33899d30be91SStefano Zampini buf_size_idxs = 0; 33909d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 33919d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 33929d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 33939d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 33949d30be91SStefano Zampini } 33959d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 33969d30be91SStefano Zampini 33979d30be91SStefano Zampini /* set preallocation */ 33989d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 33999d30be91SStefano Zampini if (!newisdense) { 34009d30be91SStefano Zampini PetscInt *new_local_nnz=0; 34019d30be91SStefano Zampini 34029d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 34039d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 34049d30be91SStefano Zampini if (n_recvs) { 34059d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 34069d30be91SStefano Zampini } 34079d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 34089d30be91SStefano Zampini PetscInt j; 34099d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 34109d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 34119d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 34129d30be91SStefano Zampini } 34139d30be91SStefano Zampini } else { 34149d30be91SStefano Zampini /* TODO */ 34159d30be91SStefano Zampini } 34169d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 34179d30be91SStefano Zampini } 34189d30be91SStefano Zampini if (new_local_nnz) { 34199d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 34209d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 34219d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 34229d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 34239d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 34249d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 34259d30be91SStefano Zampini } else { 34269d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 34279d30be91SStefano Zampini } 34289d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 34299d30be91SStefano Zampini } else { 34309d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 34319d30be91SStefano Zampini } 3432e7931f94SStefano Zampini 3433e7931f94SStefano Zampini /* set values */ 3434e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 34359d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 3436e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3437e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 3438e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 34399d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 3440e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3441e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3442e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 344328143c3dSStefano Zampini } else { 344428143c3dSStefano Zampini /* TODO */ 3445e7931f94SStefano Zampini } 3446e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3447e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 3448e7931f94SStefano Zampini } 3449e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3450e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 345170cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 345270cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 34539d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 34549d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 3455e7931f94SStefano Zampini 3456dfd14d43SStefano Zampini #if 0 345728143c3dSStefano Zampini if (!restrict_comm) { /* check */ 3458e7931f94SStefano Zampini Vec lvec,rvec; 3459e7931f94SStefano Zampini PetscReal infty_error; 3460e7931f94SStefano Zampini 34612a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 3462e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 3463e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 3464e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 346570cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 3466e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 3467e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 3468e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 3469e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 3470e7931f94SStefano Zampini } 347128143c3dSStefano Zampini #endif 3472e7931f94SStefano Zampini 347328143c3dSStefano Zampini /* assemble new additional is (if any) */ 347428143c3dSStefano Zampini if (nis) { 347528143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 347628143c3dSStefano Zampini 347728143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3478854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 347928143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 348028143c3dSStefano Zampini psum = 0; 348128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 348228143c3dSStefano Zampini for (j=0;j<nis;j++) { 348328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 348428143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 348528143c3dSStefano Zampini psum += plen; 348628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 348728143c3dSStefano Zampini } 348828143c3dSStefano Zampini } 3489854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 3490854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 349128143c3dSStefano Zampini for (i=1;i<nis;i++) { 349228143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 349328143c3dSStefano Zampini } 349428143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 349528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 349628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 349728143c3dSStefano Zampini for (j=0;j<nis;j++) { 349828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 349928143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 350028143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 350128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 350228143c3dSStefano Zampini } 350328143c3dSStefano Zampini } 350428143c3dSStefano Zampini for (i=0;i<nis;i++) { 350528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 350628143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 350728143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 350828143c3dSStefano Zampini } 350928143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 351028143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 351128143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 351228143c3dSStefano Zampini } 3513e7931f94SStefano Zampini /* free workspace */ 351428143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 3515e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3516e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 3517e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3518e7931f94SStefano Zampini if (isdense) { 3519e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3520e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3521e7931f94SStefano Zampini } else { 3522e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 3523e7931f94SStefano Zampini } 352428143c3dSStefano Zampini if (nis) { 352528143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 352628143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 352728143c3dSStefano Zampini } 3528e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 3529e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 353028143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 3531e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 3532e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 353328143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 3534e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 3535e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 3536e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 3537e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 3538e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 353928143c3dSStefano Zampini if (nis) { 354028143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 354128143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 354228143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 354328143c3dSStefano Zampini } 354428143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 354528143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 354628143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 354728143c3dSStefano Zampini for (i=0;i<nis;i++) { 354828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 354928143c3dSStefano Zampini } 355028143c3dSStefano Zampini } 3551e7931f94SStefano Zampini PetscFunctionReturn(0); 3552e7931f94SStefano Zampini } 3553a57a6d2fSStefano Zampini 355412edc857SStefano Zampini /* temporary hack into ksp private data structure */ 355512edc857SStefano Zampini #include <petsc-private/kspimpl.h> 355612edc857SStefano Zampini 3557c8587f34SStefano Zampini #undef __FUNCT__ 3558c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 3559c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 3560c8587f34SStefano Zampini { 3561c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3562c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 356320a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 35649881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 356520a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 35666e683305SStefano Zampini IS coarse_is,*isarray; 35676e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 35686e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 3569f9eb5b7dSStefano Zampini PC pc_temp; 3570c8587f34SStefano Zampini PCType coarse_pc_type; 3571c8587f34SStefano Zampini KSPType coarse_ksp_type; 3572f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 35734f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 35746e683305SStefano Zampini Mat t_coarse_mat_is; 35756e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 35766e683305SStefano Zampini PetscMPIInt all_procs; 357774e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 357868457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 357922bc73bbSStefano Zampini PetscScalar *array; 35809881197aSStefano Zampini PetscErrorCode ierr; 3581fdc09c96SStefano Zampini 3582c8587f34SStefano Zampini PetscFunctionBegin; 3583c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 358468457ee5SStefano 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 */ 358568457ee5SStefano Zampini compute_vecs = PETSC_TRUE; 3586fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 3587fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 3588f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 3589f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 3590f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 3591fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 3592fa7f1dd8SStefano Zampini if (ocoarse_size != pcbddc->coarse_size) { /* ...but with different size, so reset it and set reuse flag to false */ 3593727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3594fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3595fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 3596fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3597f4ddd8eeSStefano Zampini } 3598fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 3599fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3600f4ddd8eeSStefano Zampini } 360170cf5478SStefano Zampini /* reset any subassembling information */ 360270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 36036e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 36046e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 3605fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3606f4ddd8eeSStefano Zampini } 3607c8587f34SStefano Zampini 36086e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 36092b510759SStefano Zampini im_active = !!(pcis->n); 36102b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 36116e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 36126e683305SStefano Zampini void_procs = all_procs-active_procs; 36136e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 361474e2c79eSStefano Zampini redist = PETSC_FALSE; 361522bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 36166e683305SStefano Zampini csin_ml = PETSC_TRUE; 36176e683305SStefano Zampini ncoarse_ml = void_procs; 36186e683305SStefano Zampini csin_ds = PETSC_TRUE; 36196e683305SStefano Zampini ncoarse_ds = void_procs; 36206e683305SStefano Zampini } else { 36216e683305SStefano Zampini csin_ml = PETSC_FALSE; 36226e683305SStefano Zampini ncoarse_ml = all_procs; 36236e683305SStefano Zampini if (void_procs) { 36246e683305SStefano Zampini csin_ds = PETSC_TRUE; 36256e683305SStefano Zampini ncoarse_ds = void_procs; 36266e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 36276e683305SStefano Zampini } else { 362874e2c79eSStefano Zampini if (pcbddc->redistribute_coarse && pcbddc->redistribute_coarse < all_procs) { 362974e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 363074e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 363174e2c79eSStefano Zampini redist = PETSC_TRUE; 363274e2c79eSStefano Zampini } else { 36336e683305SStefano Zampini csin_ds = PETSC_FALSE; 36346e683305SStefano Zampini ncoarse_ds = all_procs; 36356e683305SStefano Zampini } 36366e683305SStefano Zampini } 363774e2c79eSStefano Zampini } 36386e683305SStefano Zampini 36396e683305SStefano Zampini /* 36406e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 36416e683305SStefano Zampini - we have not exceeded the number of levels requested 36426e683305SStefano Zampini - we can actually subassemble the active processes 36436e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 36446e683305SStefano Zampini */ 36456e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 36466e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 36476e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 36486e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 36496e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 3650f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 36512b510759SStefano Zampini } else { 3652f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 3653c8587f34SStefano Zampini } 3654c8587f34SStefano Zampini } 36556e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 36566e683305SStefano Zampini if (multilevel_allowed) { 36576e683305SStefano Zampini ncoarse = ncoarse_ml; 36586e683305SStefano Zampini csin = csin_ml; 36596e683305SStefano Zampini } else { 36606e683305SStefano Zampini ncoarse = ncoarse_ds; 36616e683305SStefano Zampini csin = csin_ds; 36626e683305SStefano Zampini } 3663e7931f94SStefano Zampini 3664abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 3665abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 3666abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 3667abbbba34SStefano Zampini 3668abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 366922bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 367022bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 367122bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 367222bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 3673b9b85e73SStefano Zampini #if 0 3674b9b85e73SStefano Zampini { 3675b9b85e73SStefano Zampini PetscViewer viewer; 3676b9b85e73SStefano Zampini char filename[256]; 3677b9b85e73SStefano Zampini sprintf(filename,"local_coarse_mat%d.m",PetscGlobalRank); 3678b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3679b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3680b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 3681b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3682b9b85e73SStefano Zampini } 3683b9b85e73SStefano Zampini #endif 36846e683305SStefano 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); 36856e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 36866e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 36876e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3688abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 3689abbbba34SStefano Zampini 36906e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 36916e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 36926e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 36936e683305SStefano Zampini const PetscInt *idxs; 36946e683305SStefano Zampini ISLocalToGlobalMapping tmap; 36956e683305SStefano Zampini 36966e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 36970be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 36986e683305SStefano Zampini /* allocate space for temporary storage */ 3699854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 3700854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 37016e683305SStefano Zampini /* allocate for IS array */ 37026e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 37036e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 37046e683305SStefano Zampini nis = nisdofs + nisneu; 3705854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 37066e683305SStefano Zampini /* dofs splitting */ 37076e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 37086e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 37096e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 37106e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 37116e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 37126e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 37136e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 37146e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 37156e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 37166e683305SStefano Zampini } 37176e683305SStefano Zampini /* neumann boundaries */ 37186e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 37196e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 37206e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 37216e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 37226e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 37236e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 37246e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 37256e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 37266e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 37276e683305SStefano Zampini } 37286e683305SStefano Zampini /* free memory */ 37296e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 37306e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 37316e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 37326e683305SStefano Zampini } else { 37336e683305SStefano Zampini nis = 0; 37346e683305SStefano Zampini nisdofs = 0; 37356e683305SStefano Zampini nisneu = 0; 37366e683305SStefano Zampini isarray = NULL; 37376e683305SStefano Zampini } 37386e683305SStefano Zampini /* destroy no longer needed map */ 37396e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 37406e683305SStefano Zampini 37416e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 37426e683305SStefano Zampini coarse_mat_is = NULL; 37436e683305SStefano Zampini if (csin) { 37446e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 374574e2c79eSStefano Zampini if (redist) { 374674e2c79eSStefano Zampini PetscMPIInt rank; 374774e2c79eSStefano Zampini PetscInt spc,n_spc_p1,dest[1]; 374874e2c79eSStefano Zampini 374974e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 375074e2c79eSStefano Zampini spc = all_procs/pcbddc->redistribute_coarse; 375174e2c79eSStefano Zampini n_spc_p1 = all_procs%pcbddc->redistribute_coarse; 375274e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 375374e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 375474e2c79eSStefano Zampini } else { 375574e2c79eSStefano Zampini dest[0] = rank/(spc+1); 375674e2c79eSStefano Zampini } 375774e2c79eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),1,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 375874e2c79eSStefano Zampini } else { 37596e683305SStefano Zampini PetscInt j,tissize,*nisindices; 37606e683305SStefano Zampini PetscInt *coarse_candidates; 37616e683305SStefano Zampini const PetscInt* tisindices; 37626e683305SStefano Zampini /* get coarse candidates' ranks in pc communicator */ 3763854ce69bSBarry Smith ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 37646e683305SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 37656e683305SStefano Zampini for (i=0,j=0;i<all_procs;i++) { 37666e683305SStefano Zampini if (!coarse_candidates[i]) { 37676e683305SStefano Zampini coarse_candidates[j]=i; 37686e683305SStefano Zampini j++; 37696e683305SStefano Zampini } 37706e683305SStefano Zampini } 37716e683305SStefano Zampini if (j < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",j,ncoarse); 37726e683305SStefano Zampini /* get a suitable subassembling pattern */ 37736e683305SStefano Zampini if (csin_type_simple) { 37746e683305SStefano Zampini PetscMPIInt rank; 37756e683305SStefano Zampini PetscInt issize,isidx; 37766e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 37776e683305SStefano Zampini if (im_active) { 37786e683305SStefano Zampini issize = 1; 37796e683305SStefano Zampini isidx = (PetscInt)rank; 37806e683305SStefano Zampini } else { 37816e683305SStefano Zampini issize = 0; 37826e683305SStefano Zampini isidx = -1; 37836e683305SStefano Zampini } 37846e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 37856e683305SStefano Zampini } else { 37866e683305SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,PETSC_TRUE,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 37876e683305SStefano Zampini } 37886e683305SStefano Zampini if (pcbddc->dbg_flag) { 37896e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 37906e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 37916e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 37926e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 37936e683305SStefano Zampini for (i=0;i<j;i++) { 37946e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 37956e683305SStefano Zampini } 37966e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 37976e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 37986e683305SStefano Zampini } 37996e683305SStefano Zampini /* shift the pattern on coarse candidates */ 38006e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 38016e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 3802854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 38036e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 38046e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 38056e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 38066e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 38076e683305SStefano Zampini } 380874e2c79eSStefano Zampini } 38096e683305SStefano Zampini if (pcbddc->dbg_flag) { 38106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 38116e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 38126e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 38136e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38146e683305SStefano Zampini } 38156e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 38166e683305SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 38176e683305SStefano Zampini } else { 38186e683305SStefano Zampini if (pcbddc->dbg_flag) { 38196e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 38206e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 38216e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38226e683305SStefano Zampini } 38236e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 38246e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 38256e683305SStefano Zampini } 38266e683305SStefano Zampini 38276e683305SStefano Zampini /* create local to global scatters for coarse problem */ 382868457ee5SStefano Zampini if (compute_vecs) { 38296e683305SStefano Zampini PetscInt lrows; 38306e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 38316e683305SStefano Zampini if (coarse_mat_is) { 38326e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 38336e683305SStefano Zampini } else { 38346e683305SStefano Zampini lrows = 0; 38356e683305SStefano Zampini } 38366e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 38376e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 38386e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 38396e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 38406e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 38416e683305SStefano Zampini } 38426e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 38436e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 3844c8587f34SStefano Zampini 3845f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 3846f9eb5b7dSStefano Zampini if (multilevel_allowed) { 3847f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 3848f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 3849f9eb5b7dSStefano Zampini } else { 3850f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 3851f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 3852c8587f34SStefano Zampini } 3853c8587f34SStefano Zampini 38546e683305SStefano Zampini /* print some info if requested */ 38556e683305SStefano Zampini if (pcbddc->dbg_flag) { 38566e683305SStefano Zampini if (!multilevel_allowed) { 38576e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 38586e683305SStefano Zampini if (multilevel_requested) { 38596e683305SStefano 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); 38606e683305SStefano Zampini } else if (pcbddc->max_levels) { 38616e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 38626e683305SStefano Zampini } 38636e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38646e683305SStefano Zampini } 38656e683305SStefano Zampini } 38666e683305SStefano Zampini 3867f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 38686e683305SStefano Zampini if (coarse_mat_is) { 38696e683305SStefano Zampini MatReuse coarse_mat_reuse; 38706a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 38716e683305SStefano Zampini if (pcbddc->dbg_flag) { 38726e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 38736e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 38746e683305SStefano Zampini } 3875f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 3876312be037SStefano Zampini char prefix[256],str_level[16]; 3877e604994aSStefano Zampini size_t len; 38786e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 3879c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 3880f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 38815f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 3882c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 38836e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 3884c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 3885c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 3886e604994aSStefano Zampini /* prefix */ 3887e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 3888e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 3889e604994aSStefano Zampini if (!pcbddc->current_level) { 3890e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3891e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 3892c8587f34SStefano Zampini } else { 3893e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 3894312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 3895312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 389634d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 3897312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 3898e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 3899e604994aSStefano Zampini } 3900e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 3901f9eb5b7dSStefano Zampini /* allow user customization */ 3902f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 39037e0def11SStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3904312be037SStefano Zampini } 3905f9eb5b7dSStefano Zampini 3906f9eb5b7dSStefano Zampini /* get some info after set from options */ 3907f9eb5b7dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 3908f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 3909f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 39104f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 39116e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 3912f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 3913f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 3914f9eb5b7dSStefano Zampini } 39154f3a063dSStefano Zampini if (isredundant) { 39164f3a063dSStefano Zampini KSP inner_ksp; 39174f3a063dSStefano Zampini PC inner_pc; 39184f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 39194f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 39204f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 39214f3a063dSStefano Zampini } 3922f9eb5b7dSStefano Zampini 39236e683305SStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 3924f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 3925f9eb5b7dSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 3926f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 39276e683305SStefano Zampini if (nisdofs) { 39286e683305SStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 39296e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 39306e683305SStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 39311035eff8SStefano Zampini } 39321035eff8SStefano Zampini } 39336e683305SStefano Zampini if (nisneu) { 39346e683305SStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 39356e683305SStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 39361035eff8SStefano Zampini } 3937fdc09c96SStefano Zampini 3938f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 3939fa7f1dd8SStefano Zampini if (coarse_reuse) { 394081d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 3941fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 39426e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 3943fa7f1dd8SStefano Zampini } else { 39446e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 3945fa7f1dd8SStefano Zampini } 3946c8587f34SStefano Zampini if (isbddc || isnn) { 394722bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 394870cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 394928143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,PETSC_TRUE,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 395022b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 39516e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 39526e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 39536e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 39546e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 395522b6e8a2SStefano Zampini } 395670cf5478SStefano Zampini } 39576e683305SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 395870cf5478SStefano Zampini } else { 395922bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 396022bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 396122bc73bbSStefano Zampini } 396222bc73bbSStefano Zampini } else { 39632e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 3964c8587f34SStefano Zampini } 3965c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 3966c8587f34SStefano Zampini 3967c8587f34SStefano Zampini /* propagate symmetry info to coarse matrix */ 3968b9d89cd5SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 39695a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 3970c8587f34SStefano Zampini 39716e683305SStefano Zampini /* set operators */ 39725f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 39736e683305SStefano Zampini if (pcbddc->dbg_flag) { 39746e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 39756e683305SStefano Zampini } 39766e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 39776e683305SStefano Zampini coarse_mat = 0; 39786e683305SStefano Zampini } 39796e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 3980b9b85e73SStefano Zampini #if 0 3981b9b85e73SStefano Zampini { 3982b9b85e73SStefano Zampini PetscViewer viewer; 3983b9b85e73SStefano Zampini char filename[256]; 3984b9b85e73SStefano Zampini sprintf(filename,"coarse_mat.m"); 3985b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,filename,&viewer);CHKERRQ(ierr); 3986b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3987b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 3988b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3989b9b85e73SStefano Zampini } 3990b9b85e73SStefano Zampini #endif 3991c8587f34SStefano Zampini 3992c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 3993c8587f34SStefano Zampini if (pcbddc->NullSpace) { 3994c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 399598a51de6SStefano Zampini } 399698a51de6SStefano Zampini 399798a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 399898a51de6SStefano Zampini Vec crhs,csol; 399998a51de6SStefano Zampini PetscBool ispreonly; 400098a51de6SStefano Zampini if (CoarseNullSpace) { 4001c8587f34SStefano Zampini if (isbddc) { 4002c8587f34SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4003c8587f34SStefano Zampini } else { 4004c8587f34SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 4005c8587f34SStefano Zampini } 4006c8587f34SStefano Zampini } 4007f9eb5b7dSStefano Zampini /* setup coarse ksp */ 4008f9eb5b7dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4009f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4010f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 40116e683305SStefano Zampini /* hack */ 4012f347579bSStefano Zampini if (!csol) { 40132a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4014f9eb5b7dSStefano Zampini } 4015f347579bSStefano Zampini if (!crhs) { 40162a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4017f347579bSStefano Zampini } 4018cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4019cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 40206e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4021c8587f34SStefano Zampini KSP check_ksp; 40222b510759SStefano Zampini KSPType check_ksp_type; 4023c8587f34SStefano Zampini PC check_pc; 40246e683305SStefano Zampini Vec check_vec,coarse_vec; 40256a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 40262b510759SStefano Zampini PetscInt its; 40276e683305SStefano Zampini PetscBool compute_eigs; 40286e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 40296e683305SStefano Zampini PetscInt neigs; 40308e185a42SStefano Zampini const char *prefix; 4031c8587f34SStefano Zampini 40322b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 40336e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 403423ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4035f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 40362b510759SStefano Zampini if (ispreonly) { 40372b510759SStefano Zampini check_ksp_type = KSPPREONLY; 40386e683305SStefano Zampini compute_eigs = PETSC_FALSE; 40392b510759SStefano Zampini } else { 4040cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 40416e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4042c8587f34SStefano Zampini } 4043c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 40446e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 40456e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 40466e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 4047a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 4048a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 4049a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 4050a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 4051c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4052c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4053c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4054c8587f34SStefano Zampini /* create random vec */ 40556e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 40566e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 4057c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 4058c8587f34SStefano Zampini if (CoarseNullSpace) { 4059c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 4060c8587f34SStefano Zampini } 40616e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 4062c8587f34SStefano Zampini /* solve coarse problem */ 40636e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 4064c8587f34SStefano Zampini if (CoarseNullSpace) { 40656e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 4066c8587f34SStefano Zampini } 4067cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 40686e683305SStefano Zampini if (compute_eigs) { 4069854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 4070854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 40716e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 40726e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 40736e683305SStefano Zampini lambda_min = eigs_r[0]; 40746e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 40756e683305SStefano Zampini if (lambda_max>lambda_min) { 4076cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 4077cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 4078cbcc2c2aSStefano Zampini } 4079c8587f34SStefano Zampini } 4080c8587f34SStefano Zampini } 4081cbcc2c2aSStefano Zampini 4082c8587f34SStefano Zampini /* check coarse problem residual error */ 40836e683305SStefano Zampini if (pcbddc->dbg_flag) { 40846e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 40856e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 40866e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 4087c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 40886e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 40896e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 4090c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 40916e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (%d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 40926e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 40936e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 40946e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 40956e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 40966e683305SStefano Zampini if (compute_eigs) { 40976e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 4098deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 4099c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 41006e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 41016e683305SStefano 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); 41026e683305SStefano Zampini for (i=0;i<neigs;i++) { 41036e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 4104c8587f34SStefano Zampini } 41056e683305SStefano Zampini } 41066e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 41076e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 41086e683305SStefano Zampini } 4109c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 41106e683305SStefano Zampini if (compute_eigs) { 41116e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 41126e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 4113c8587f34SStefano Zampini } 41146e683305SStefano Zampini } 41156e683305SStefano Zampini } 4116cbcc2c2aSStefano Zampini /* print additional info */ 4117cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 41186e683305SStefano Zampini /* waits until all processes reaches this point */ 41196e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 4120cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 4121cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4122cbcc2c2aSStefano Zampini } 4123cbcc2c2aSStefano Zampini 41242b510759SStefano Zampini /* free memory */ 4125c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4126fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 4127c8587f34SStefano Zampini PetscFunctionReturn(0); 4128c8587f34SStefano Zampini } 4129674ae819SStefano Zampini 4130f34684f1SStefano Zampini #undef __FUNCT__ 4131f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 4132f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 4133f34684f1SStefano Zampini { 4134f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4135f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 4136f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4137727cdba6SStefano Zampini PetscInt i,coarse_size; 4138727cdba6SStefano Zampini PetscInt *local_primal_indices; 4139f34684f1SStefano Zampini PetscErrorCode ierr; 4140f34684f1SStefano Zampini 4141f34684f1SStefano Zampini PetscFunctionBegin; 4142f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 414389c96988SStefano Zampini if (!pcbddc->primal_indices_local_idxs && pcbddc->local_primal_size) { 414489c96988SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Local primal indices have not been created"); 4145727cdba6SStefano Zampini } 4146727cdba6SStefano 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); 4147f34684f1SStefano Zampini 4148f34684f1SStefano Zampini /* check numbering */ 4149f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 4150f34684f1SStefano Zampini PetscScalar coarsesum,*array; 4151b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 4152f34684f1SStefano Zampini 4153f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4154f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4155f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 41560fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 4157f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 4158f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4159727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4160f34684f1SStefano Zampini } 4161f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4162f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4163f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4164f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4165f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4166f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4167f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4168f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4169f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4170f34684f1SStefano Zampini if (array[i] == 1.0) { 4171b9b85e73SStefano Zampini set_error = PETSC_TRUE; 4172f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a single process!\n",PetscGlobalRank,i);CHKERRQ(ierr); 4173f34684f1SStefano Zampini } 4174f34684f1SStefano Zampini } 4175b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4176f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4177f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4178f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 4179f34684f1SStefano Zampini } 4180f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);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 = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 4185f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 4186b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 4187f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 4188f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4189f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4190f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4191727cdba6SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i]); 4192f34684f1SStefano Zampini } 4193f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4194f34684f1SStefano Zampini } 4195f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4196b9b85e73SStefano Zampini if (set_error_reduced) { 4197b9b85e73SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 4198b9b85e73SStefano Zampini } 4199f34684f1SStefano Zampini } 4200f34684f1SStefano Zampini /* get back data */ 4201f34684f1SStefano Zampini *coarse_size_n = coarse_size; 4202f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 4203674ae819SStefano Zampini PetscFunctionReturn(0); 4204674ae819SStefano Zampini } 4205674ae819SStefano Zampini 4206e456f2a8SStefano Zampini #undef __FUNCT__ 4207e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 4208a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 4209e456f2a8SStefano Zampini { 4210e456f2a8SStefano Zampini IS localis_t; 4211a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 4212e456f2a8SStefano Zampini PetscScalar *vals; 4213e456f2a8SStefano Zampini PetscErrorCode ierr; 4214e456f2a8SStefano Zampini 4215e456f2a8SStefano Zampini PetscFunctionBegin; 4216a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 4217e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 4218854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 4219e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 4220e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4221a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 4222a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 42231035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 4224a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 42251035eff8SStefano Zampini } 4226a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 4227e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4228e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4229a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 4230a7dc3881SStefano Zampini /* now compute set in local ordering */ 4231a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4232a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4233a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4234a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 4235a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4236ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4237e456f2a8SStefano Zampini lsize++; 4238e456f2a8SStefano Zampini } 4239e456f2a8SStefano Zampini } 4240854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 4241a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4242ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4243e456f2a8SStefano Zampini idxs[lsize++] = i; 4244e456f2a8SStefano Zampini } 4245e456f2a8SStefano Zampini } 4246a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4247a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 4248e456f2a8SStefano Zampini *localis = localis_t; 4249e456f2a8SStefano Zampini PetscFunctionReturn(0); 4250e456f2a8SStefano Zampini } 4251906d46d4SStefano Zampini 4252906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 4253906d46d4SStefano Zampini #undef __FUNCT__ 4254906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 4255906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 4256906d46d4SStefano Zampini { 4257906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4258906d46d4SStefano Zampini PetscErrorCode ierr; 4259906d46d4SStefano Zampini 4260906d46d4SStefano Zampini PetscFunctionBegin; 4261906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4262906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4263906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4264906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4265906d46d4SStefano Zampini PetscFunctionReturn(0); 4266906d46d4SStefano Zampini } 4267906d46d4SStefano Zampini 4268906d46d4SStefano Zampini #undef __FUNCT__ 4269906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 4270906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 4271906d46d4SStefano Zampini { 4272906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4273906d46d4SStefano Zampini PetscErrorCode ierr; 4274906d46d4SStefano Zampini 4275906d46d4SStefano Zampini PetscFunctionBegin; 4276906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4277906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4278906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4279906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4280906d46d4SStefano Zampini PetscFunctionReturn(0); 4281906d46d4SStefano Zampini } 4282