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 8674ae819SStefano Zampini #undef __FUNCT__ 9*5408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 10*5408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 11*5408967cSStefano Zampini { 12*5408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13*5408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 14*5408967cSStefano Zampini PetscErrorCode ierr; 15*5408967cSStefano Zampini 16*5408967cSStefano Zampini PetscFunctionBegin; 17*5408967cSStefano Zampini if (zerodiag) { 18*5408967cSStefano Zampini Mat A; 19*5408967cSStefano Zampini Vec vec3_N; 20*5408967cSStefano Zampini IS dirIS = NULL; 21*5408967cSStefano Zampini PetscScalar *vals; 22*5408967cSStefano Zampini const PetscInt *idxs; 23*5408967cSStefano Zampini PetscInt i,nz; 24*5408967cSStefano Zampini 25*5408967cSStefano Zampini /* p0 */ 26*5408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 27*5408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 28*5408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 29*5408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 30*5408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; /* TODO add quadrature */ 31*5408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 32*5408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 33*5408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 34*5408967cSStefano Zampini /* v_I */ 35*5408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 36*5408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 37*5408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 38*5408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 39*5408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 40*5408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 41*5408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 42*5408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 43*5408967cSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 44*5408967cSStefano Zampini if (dirIS) { 45*5408967cSStefano Zampini PetscInt n; 46*5408967cSStefano Zampini 47*5408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 48*5408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 49*5408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 50*5408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 51*5408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 52*5408967cSStefano Zampini } 53*5408967cSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 54*5408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 55*5408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 56*5408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 57*5408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 58*5408967cSStefano Zampini ierr = MatISGetLocalMat(pc->mat,&A);CHKERRQ(ierr); 59*5408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 60*5408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 61*5408967cSStefano Zampini if (PetscAbsScalar(vals[0]) > PETSC_SMALL) { /* TODO: should I add the A-norm in test? */ 62*5408967cSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! b(v_I,p_0) = %f (should be numerically 0.)",PetscAbsScalar(vals[0])); 63*5408967cSStefano Zampini } 64*5408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 65*5408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 66*5408967cSStefano Zampini } 67*5408967cSStefano Zampini 68*5408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 69*5408967cSStefano Zampini if (pcbddc->benign_saddle_point) { 70*5408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 71*5408967cSStefano Zampini pcbddc->benign_p0 = -PetscGlobalRank; 72*5408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 73*5408967cSStefano Zampini pcbddc->benign_p0 = 1; 74*5408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 75*5408967cSStefano Zampini if (pcbddc->benign_p0_gidx >=0 && pcbddc->benign_p0 != -PetscGlobalRank) { 76*5408967cSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %1.4e instead of %1.4e\n",pcbddc->benign_p0,-PetscGlobalRank);CHKERRQ(ierr); 77*5408967cSStefano Zampini } 78*5408967cSStefano Zampini } 79*5408967cSStefano Zampini PetscFunctionReturn(0); 80*5408967cSStefano Zampini } 81*5408967cSStefano Zampini 82*5408967cSStefano Zampini #undef __FUNCT__ 83339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 84339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 85339f8db1SStefano Zampini { 86339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 87339f8db1SStefano Zampini IS zerodiag; 88339f8db1SStefano Zampini PetscInt nz; 89339f8db1SStefano Zampini PetscBool sorted; 90339f8db1SStefano Zampini PetscErrorCode ierr; 91339f8db1SStefano Zampini 92339f8db1SStefano Zampini PetscFunctionBegin; 93339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 94339f8db1SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->local_mat);CHKERRQ(ierr); 95339f8db1SStefano Zampini pcbddc->benign_original_mat = pcbddc->local_mat; 96339f8db1SStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->benign_original_mat,&zerodiag);CHKERRQ(ierr); 97339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 98339f8db1SStefano Zampini if (!sorted) { 99339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 100339f8db1SStefano Zampini } 101339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 102339f8db1SStefano Zampini if (nz) { 103339f8db1SStefano Zampini IS zerodiagc; 104339f8db1SStefano Zampini PetscScalar *array; 105339f8db1SStefano Zampini const PetscInt *idxs,*idxsc; 106339f8db1SStefano Zampini PetscInt i,n,*nnz; 107339f8db1SStefano Zampini 108339f8db1SStefano Zampini /* TODO: add check for shared dofs and raise error */ 109339f8db1SStefano Zampini ierr = MatGetLocalSize(pcbddc->benign_original_mat,&n,NULL);CHKERRQ(ierr); 110339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 111339f8db1SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 112339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 113339f8db1SStefano Zampini /* local change of basis for pressures */ 114339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 115339f8db1SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->benign_original_mat),&pcbddc->benign_change);CHKERRQ(ierr); 116339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 117339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 118339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 119339f8db1SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities */ 120339f8db1SStefano Zampini for (i=0;i<nz-1;i++) nnz[idxs[i]] = 2; /* change on pressures */ 121339f8db1SStefano Zampini nnz[idxs[nz-1]] = nz; /* last local pressure dof: _0 set */ 122339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 123339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 124339f8db1SStefano Zampini /* set identity on velocities */ 125339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 126339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 127339f8db1SStefano Zampini } 128339f8db1SStefano Zampini /* set change on pressures */ 129339f8db1SStefano Zampini for (i=0;i<nz-1;i++) { 130339f8db1SStefano Zampini PetscScalar vals[2]; 131339f8db1SStefano Zampini PetscInt cols[2]; 132339f8db1SStefano Zampini 133339f8db1SStefano Zampini /* TODO: add quadrature */ 134339f8db1SStefano Zampini cols[0] = idxs[i]; 135339f8db1SStefano Zampini cols[1] = idxs[nz-1]; 136339f8db1SStefano Zampini vals[0] = 1.; 137339f8db1SStefano Zampini vals[1] = 1./nz; 138339f8db1SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+i,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 139339f8db1SStefano Zampini } 140339f8db1SStefano Zampini ierr = PetscMalloc1(nz,&array);CHKERRQ(ierr); 141339f8db1SStefano Zampini for (i=0;i<nz-1;i++) array[i] = -1.; 142339f8db1SStefano Zampini array[nz-1] = 1./nz; 143339f8db1SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nz-1,nz,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 144339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 145339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 146339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 147339f8db1SStefano Zampini /* TODO: need optimization? */ 148339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 149339f8db1SStefano Zampini ierr = MatPtAP(pcbddc->benign_original_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 150339f8db1SStefano Zampini /* store local and global idxs for p0 */ 151339f8db1SStefano Zampini pcbddc->benign_p0_lidx = idxs[nz-1]; 152339f8db1SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,1,&idxs[nz-1],&pcbddc->benign_p0_gidx);CHKERRQ(ierr); 153339f8db1SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 154339f8db1SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 155339f8db1SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 156339f8db1SStefano Zampini } else { /* this is unlikely to happen but, just in case, destroy the empty IS */ 157339f8db1SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 158339f8db1SStefano Zampini } 159339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 160339f8db1SStefano Zampini PetscFunctionReturn(0); 161339f8db1SStefano Zampini } 162339f8db1SStefano Zampini 163339f8db1SStefano Zampini #undef __FUNCT__ 164015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 165015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 166efc2fbd9SStefano Zampini { 167efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 168efc2fbd9SStefano Zampini PetscErrorCode ierr; 169efc2fbd9SStefano Zampini 170efc2fbd9SStefano Zampini PetscFunctionBegin; 171efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 172efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 173c9ed8603SStefano Zampini if (pcbddc->benign_p0_gidx >= 0) { 174efc2fbd9SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,1,NULL,PETSC_OWN_POINTER,&pcbddc->benign_p0_gidx);CHKERRQ(ierr); 175c9ed8603SStefano Zampini } else { 176c9ed8603SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,0,NULL,PETSC_OWN_POINTER,&pcbddc->benign_p0_gidx);CHKERRQ(ierr); 177c9ed8603SStefano Zampini } 178efc2fbd9SStefano Zampini } 179015636ebSStefano Zampini if (get) { /* use SF to get values */ 180efc2fbd9SStefano Zampini PetscScalar *array; 181efc2fbd9SStefano Zampini 182efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 183efc2fbd9SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,&pcbddc->benign_p0);CHKERRQ(ierr); 184efc2fbd9SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,&pcbddc->benign_p0);CHKERRQ(ierr); 185efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 186efc2fbd9SStefano Zampini } else { /* use VecSetValue */ 187c9ed8603SStefano Zampini if (pcbddc->benign_p0_gidx >= 0) { 188efc2fbd9SStefano Zampini ierr = VecSetValue(v,pcbddc->benign_p0_gidx,pcbddc->benign_p0,INSERT_VALUES);CHKERRQ(ierr); 189c9ed8603SStefano Zampini } 190efc2fbd9SStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 191efc2fbd9SStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 192efc2fbd9SStefano Zampini } 193efc2fbd9SStefano Zampini PetscFunctionReturn(0); 194efc2fbd9SStefano Zampini } 195efc2fbd9SStefano Zampini 196efc2fbd9SStefano Zampini #undef __FUNCT__ 197c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 198c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 199c263805aSStefano Zampini { 200c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 201c263805aSStefano Zampini PetscErrorCode ierr; 202c263805aSStefano Zampini 203c263805aSStefano Zampini PetscFunctionBegin; 204c263805aSStefano Zampini /* TODO: add error checking 205c263805aSStefano Zampini - avoid nested pop (or push) calls. 206c263805aSStefano Zampini - cannot push before pop. 2071c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 208c263805aSStefano Zampini */ 209c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx < 0) { 210efc2fbd9SStefano Zampini PetscFunctionReturn(0); 211efc2fbd9SStefano Zampini } 212c263805aSStefano Zampini if (pop) { 213c263805aSStefano Zampini const PetscInt *cB0_cols; 214c263805aSStefano Zampini PetscInt cB0_ncol; 215c263805aSStefano Zampini const PetscScalar *cB0_vals; 216c263805aSStefano Zampini 217c263805aSStefano Zampini /* extract B_0 */ 218efc2fbd9SStefano Zampini ierr = MatGetRow(pcbddc->local_mat,pcbddc->benign_p0_lidx,&cB0_ncol,&cB0_cols,&cB0_vals);CHKERRQ(ierr); 219c263805aSStefano Zampini pcbddc->B0_ncol = cB0_ncol; 220c263805aSStefano Zampini ierr = PetscFree2(pcbddc->B0_cols,pcbddc->B0_vals);CHKERRQ(ierr); 221c263805aSStefano Zampini ierr = PetscMalloc2(cB0_ncol,&pcbddc->B0_cols,cB0_ncol,&pcbddc->B0_vals);CHKERRQ(ierr); 222c263805aSStefano Zampini ierr = PetscMemcpy(pcbddc->B0_cols,cB0_cols,cB0_ncol*sizeof(PetscInt));CHKERRQ(ierr); 223c263805aSStefano Zampini ierr = PetscMemcpy(pcbddc->B0_vals,cB0_vals,cB0_ncol*sizeof(PetscScalar));CHKERRQ(ierr); 224efc2fbd9SStefano Zampini ierr = MatRestoreRow(pcbddc->local_mat,pcbddc->benign_p0_lidx,&cB0_ncol,&cB0_cols,&cB0_vals);CHKERRQ(ierr); 225c263805aSStefano Zampini /* remove rows and cols from local problem */ 226c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 227efc2fbd9SStefano Zampini ierr = MatZeroRowsColumns(pcbddc->local_mat,1,&pcbddc->benign_p0_lidx,1.,NULL,NULL);CHKERRQ(ierr); 228c263805aSStefano Zampini } else { /* push */ 229efc2fbd9SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,&pcbddc->benign_p0_lidx,pcbddc->B0_ncol,pcbddc->B0_cols,pcbddc->B0_vals,INSERT_VALUES);CHKERRQ(ierr); 230efc2fbd9SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,pcbddc->B0_ncol,pcbddc->B0_cols,1,&pcbddc->benign_p0_lidx,pcbddc->B0_vals,INSERT_VALUES);CHKERRQ(ierr); 231efc2fbd9SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx,pcbddc->benign_p0_lidx,0.0,INSERT_VALUES);CHKERRQ(ierr); 232c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 233c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 234c263805aSStefano Zampini } 235c263805aSStefano Zampini PetscFunctionReturn(0); 236c263805aSStefano Zampini } 237c263805aSStefano Zampini 238c263805aSStefano Zampini #undef __FUNCT__ 239b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 24008122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 241b1b3d7a2SStefano Zampini { 242b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24308122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 24408122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 24508122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 24608122e43SStefano Zampini PetscScalar *work,lwork; 24708122e43SStefano Zampini PetscScalar *St,*S,*eigv; 24808122e43SStefano Zampini PetscScalar *Sarray,*Starray; 24908122e43SStefano Zampini PetscReal *eigs,thresh; 2501b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 251f6f667cfSStefano Zampini PetscBool allocated_S_St; 25208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 25308122e43SStefano Zampini PetscReal *rwork; 25408122e43SStefano Zampini #endif 255b1b3d7a2SStefano Zampini PetscErrorCode ierr; 256b1b3d7a2SStefano Zampini 257b1b3d7a2SStefano Zampini PetscFunctionBegin; 25808122e43SStefano Zampini if (!sub_schurs->use_mumps) { 25908122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS"); 26008122e43SStefano Zampini } 26108122e43SStefano Zampini 26206a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 26306a4e24aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for general matrix pencils (herm %d, posdef %d)\n",sub_schurs->is_hermitian,sub_schurs->is_posdef); 26406a4e24aSStefano Zampini } 26506a4e24aSStefano Zampini 266fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 267fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 268fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 269fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 270fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 271fd14bc51SStefano Zampini } 272fd14bc51SStefano Zampini 273e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 274e496cd5dSStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %d (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef); 275e496cd5dSStefano Zampini } 276e496cd5dSStefano Zampini 27708122e43SStefano Zampini /* max size of subsets */ 27808122e43SStefano Zampini mss = 0; 27908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 28008122e43SStefano Zampini PetscInt subset_size; 281862806e4SStefano Zampini 28208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 28308122e43SStefano Zampini mss = PetscMax(mss,subset_size); 28408122e43SStefano Zampini } 28508122e43SStefano Zampini 28608122e43SStefano Zampini /* min/max and threshold */ 28708122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 288f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 28908122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 290f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 291f6f667cfSStefano Zampini if (nmin) { 292f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 293f6f667cfSStefano Zampini } 29408122e43SStefano Zampini 29508122e43SStefano Zampini /* allocate lapack workspace */ 29608122e43SStefano Zampini cum = cum2 = 0; 29708122e43SStefano Zampini maxneigs = 0; 29808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 29908122e43SStefano Zampini PetscInt n,subset_size; 300f6f667cfSStefano Zampini 30108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 30208122e43SStefano Zampini n = PetscMin(subset_size,nmax); 3039162d606SStefano Zampini cum += subset_size; 3049162d606SStefano Zampini cum2 += subset_size*n; 30508122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 30608122e43SStefano Zampini } 30708122e43SStefano Zampini if (mss) { 3089ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 30908122e43SStefano Zampini PetscBLASInt B_itype = 1; 31008122e43SStefano Zampini PetscBLASInt B_N = mss; 3114c6709b3SStefano Zampini PetscReal zero = 0.0; 3124c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 31308122e43SStefano Zampini 31408122e43SStefano Zampini B_lwork = -1; 31508122e43SStefano Zampini S = NULL; 31608122e43SStefano Zampini St = NULL; 317a58a30b4SStefano Zampini eigs = NULL; 318a58a30b4SStefano Zampini eigv = NULL; 319a58a30b4SStefano Zampini B_iwork = NULL; 320a58a30b4SStefano Zampini B_ifail = NULL; 321d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 322d1710679SStefano Zampini rwork = NULL; 323d1710679SStefano Zampini #endif 3248bec7fa6SStefano Zampini thresh = 1.0; 32508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 32608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32708122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_dummyint,&B_dummyint,&eps,&B_neigs,eigs,eigv,&B_N,&lwork,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 32808122e43SStefano Zampini #else 32908122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_dummyint,&B_dummyint,&eps,&B_neigs,eigs,eigv,&B_N,&lwork,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33008122e43SStefano Zampini #endif 33108122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 33208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 33308122e43SStefano Zampini } else { 33408122e43SStefano Zampini /* TODO */ 33508122e43SStefano Zampini } 33608122e43SStefano Zampini } else { 33708122e43SStefano Zampini lwork = 0; 33808122e43SStefano Zampini } 33908122e43SStefano Zampini 34008122e43SStefano Zampini nv = 0; 341d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { /* complement set of active subsets, each entry is a vertex (boundary made by active subsets, vertices and dirichlet dofs) */ 342d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 34308122e43SStefano Zampini } 3444c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 345f6f667cfSStefano Zampini if (allocated_S_St) { 346f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 347f6f667cfSStefano Zampini } 348f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 34908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 35008122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 35108122e43SStefano Zampini #endif 3529162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 3539162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 3549162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 35508122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 3569162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 35708122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 35808122e43SStefano Zampini 35908122e43SStefano Zampini maxneigs = 0; 36008122e43SStefano Zampini cum = cum2 = cumarray = 0; 3619162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 3629162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 363d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 36408122e43SStefano Zampini const PetscInt *idxs; 36508122e43SStefano Zampini 366d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 36708122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 36808122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 36908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 37008122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 3719162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 3729162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 37308122e43SStefano Zampini } 37408122e43SStefano Zampini cum2 = cum; 375d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 37608122e43SStefano Zampini } 37708122e43SStefano Zampini 37808122e43SStefano Zampini if (mss) { /* multilevel */ 37908122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 38008122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 38108122e43SStefano Zampini } 38208122e43SStefano Zampini 38308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 38408122e43SStefano Zampini 38508122e43SStefano Zampini const PetscInt *idxs; 386f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 387862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 38808122e43SStefano Zampini PetscBLASInt B_N; 389aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 39008122e43SStefano Zampini 391862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 392f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 393f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 3949ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 395aff50787SStefano Zampini PetscInt j,k; 396aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 397aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 398aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 39908122e43SStefano Zampini } 40008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 401aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 402aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 403aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 404aff50787SStefano Zampini } 40508122e43SStefano Zampini } 40608122e43SStefano Zampini } else { 40708122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 40808122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 40908122e43SStefano Zampini } 4108bec7fa6SStefano Zampini } else { 411f6f667cfSStefano Zampini S = Sarray + cumarray; 412f6f667cfSStefano Zampini St = Starray + cumarray; 4138bec7fa6SStefano Zampini } 41408122e43SStefano Zampini 415f6f667cfSStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 416aff50787SStefano Zampini /* see if we can save some work */ 417aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 418aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 419aff50787SStefano Zampini } 420aff50787SStefano Zampini 421aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 422aff50787SStefano Zampini B_neigs = 0; 423aff50787SStefano Zampini } else { 424aff50787SStefano Zampini /* Threshold: this is an heuristic for edges */ 425f6f667cfSStefano Zampini thresh = pcbddc->mat_graph->count[idxs[0]]*pcbddc->adaptive_threshold; 426f6f667cfSStefano Zampini 4279ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 42808122e43SStefano Zampini PetscBLASInt B_itype = 1; 429f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 4304c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 4319552c7c7SStefano Zampini PetscInt nmin_s; 43208122e43SStefano Zampini 433fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 4348bec7fa6SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d %d %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]); 435fd14bc51SStefano Zampini } 436d16cbb6bSStefano Zampini 43708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 438d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 439d16cbb6bSStefano Zampini 440d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 44108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 442f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 44308122e43SStefano Zampini #else 444f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 44508122e43SStefano Zampini #endif 446d16cbb6bSStefano Zampini } else { 447d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 448d16cbb6bSStefano Zampini B_IL = 1; 449d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 450d16cbb6bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 451d16cbb6bSStefano Zampini #else 452d16cbb6bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 453d16cbb6bSStefano Zampini #endif 454d16cbb6bSStefano Zampini } 45508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 45608122e43SStefano Zampini if (B_ierr) { 45708122e43SStefano Zampini if (B_ierr < 0 ) { 45808122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 45908122e43SStefano Zampini } else if (B_ierr <= B_N) { 46008122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 46108122e43SStefano Zampini } else { 4629552c7c7SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 46308122e43SStefano Zampini } 46408122e43SStefano Zampini } 46508122e43SStefano Zampini 46608122e43SStefano Zampini if (B_neigs > nmax) { 467fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 468fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 469fd14bc51SStefano Zampini } 470f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 47108122e43SStefano Zampini B_neigs = nmax; 47208122e43SStefano Zampini } 47308122e43SStefano Zampini 4749552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 4759552c7c7SStefano Zampini if (B_neigs < nmin_s) { 47608122e43SStefano Zampini PetscBLASInt B_neigs2; 47708122e43SStefano Zampini 478f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 479f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 480fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 481fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, less than minimum required %d. Asking for %d to %d incl (fortran like)\n",B_neigs,nmin,B_IL,B_IU); 482fd14bc51SStefano Zampini } 4839ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 48408122e43SStefano Zampini PetscInt j; 48508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 48608122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 48708122e43SStefano Zampini } 48808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 48908122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 49008122e43SStefano Zampini } 49108122e43SStefano Zampini } else { 49208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 49308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 49408122e43SStefano Zampini } 49508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 49608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 497f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 49808122e43SStefano Zampini #else 499f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 50008122e43SStefano Zampini #endif 50108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 50208122e43SStefano Zampini B_neigs += B_neigs2; 50308122e43SStefano Zampini } 50408122e43SStefano Zampini if (B_ierr) { 50508122e43SStefano Zampini if (B_ierr < 0 ) { 50608122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 50708122e43SStefano Zampini } else if (B_ierr <= B_N) { 50808122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 50908122e43SStefano Zampini } else { 5109552c7c7SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 51108122e43SStefano Zampini } 51208122e43SStefano Zampini } 513fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 514ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 51508122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 51608122e43SStefano Zampini if (eigs[j] == 0.0) { 517ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 51808122e43SStefano Zampini } else { 519ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 520fd14bc51SStefano Zampini } 52108122e43SStefano Zampini } 52208122e43SStefano Zampini } 52308122e43SStefano Zampini } else { 52408122e43SStefano Zampini /* TODO */ 52508122e43SStefano Zampini } 526aff50787SStefano Zampini } 5278bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 5288bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 5299162d606SStefano Zampini if (B_neigs) { 5309162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 531fd14bc51SStefano Zampini 532fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 5339552c7c7SStefano Zampini PetscInt ii; 5349552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 535ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 5369552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 537ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 538ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 539ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 540ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 541ac47001eSStefano Zampini #else 542ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]);CHKERRQ(ierr); 543ac47001eSStefano Zampini #endif 5449552c7c7SStefano Zampini } 5459552c7c7SStefano Zampini } 546fd14bc51SStefano Zampini } 54708122e43SStefano Zampini #if 0 5489162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 54908122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 55008122e43SStefano Zampini PetscScalar norm; 55108122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 5529162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 5539162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 55408122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 55508122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 55608122e43SStefano Zampini } else { 55708122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 55808122e43SStefano Zampini } 5599162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 560b1b3d7a2SStefano Zampini } 561b1b3d7a2SStefano Zampini #endif 5629162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 5639162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 5649162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 5659162d606SStefano Zampini cum++; 56608122e43SStefano Zampini } 56708122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 56808122e43SStefano Zampini /* shift for next computation */ 56908122e43SStefano Zampini cumarray += subset_size*subset_size; 57008122e43SStefano Zampini } 571fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 572fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 573fd14bc51SStefano Zampini } 57408122e43SStefano Zampini 57508122e43SStefano Zampini if (mss) { 57608122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 57708122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 578f6f667cfSStefano Zampini /* destroy matrices (junk) */ 579f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 580f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 58108122e43SStefano Zampini } 582f6f667cfSStefano Zampini if (allocated_S_St) { 583f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 584f6f667cfSStefano Zampini } 585f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 58608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 58708122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 58808122e43SStefano Zampini #endif 58908122e43SStefano Zampini if (pcbddc->dbg_flag) { 5901b968477SStefano Zampini PetscInt maxneigs_r; 59108122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5929b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 59308122e43SStefano Zampini } 59408122e43SStefano Zampini PetscFunctionReturn(0); 59508122e43SStefano Zampini } 596b1b3d7a2SStefano Zampini 597674ae819SStefano Zampini #undef __FUNCT__ 598c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 599c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 600c8587f34SStefano Zampini { 601c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6028629588bSStefano Zampini PetscScalar *coarse_submat_vals; 603c8587f34SStefano Zampini PetscErrorCode ierr; 604c8587f34SStefano Zampini 605c8587f34SStefano Zampini PetscFunctionBegin; 606f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 6075e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 608c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 609c8587f34SStefano Zampini 610684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 6110fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 612684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 613c8587f34SStefano Zampini 614c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 615b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 616c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 617c8587f34SStefano Zampini } 618c8587f34SStefano Zampini 6198629588bSStefano Zampini /* 6208629588bSStefano Zampini Setup local correction and local part of coarse basis. 6218629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 6228629588bSStefano Zampini */ 62347f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 6248629588bSStefano Zampini 6258629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 6268629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 6278629588bSStefano Zampini 6288629588bSStefano Zampini /* free */ 6298629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 630c8587f34SStefano Zampini PetscFunctionReturn(0); 631c8587f34SStefano Zampini } 632c8587f34SStefano Zampini 633c8587f34SStefano Zampini #undef __FUNCT__ 634674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 635674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 636674ae819SStefano Zampini { 637674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 638674ae819SStefano Zampini PetscErrorCode ierr; 639674ae819SStefano Zampini 640674ae819SStefano Zampini PetscFunctionBegin; 641674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 642674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 643674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 644674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 645785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 646674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 647f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 648f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 649785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 65063602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 65163602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 652674ae819SStefano Zampini PetscFunctionReturn(0); 653674ae819SStefano Zampini } 654674ae819SStefano Zampini 655674ae819SStefano Zampini #undef __FUNCT__ 656674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 657674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 658674ae819SStefano Zampini { 659674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 660674ae819SStefano Zampini PetscErrorCode ierr; 661674ae819SStefano Zampini 662674ae819SStefano Zampini PetscFunctionBegin; 663b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 664674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 665674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 666674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 667b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 668674ae819SStefano Zampini PetscFunctionReturn(0); 669674ae819SStefano Zampini } 670674ae819SStefano Zampini 671674ae819SStefano Zampini #undef __FUNCT__ 672674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 673674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 674674ae819SStefano Zampini { 675674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 67606656605SStefano Zampini PetscScalar *array; 677674ae819SStefano Zampini PetscErrorCode ierr; 678674ae819SStefano Zampini 679674ae819SStefano Zampini PetscFunctionBegin; 680674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 68158da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 68206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 68306656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 68458da7f69SStefano Zampini } 685674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 686674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 68715aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 68815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 689674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 690674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 691674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 69206656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 693674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 694674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 6958ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 696674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 697674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 698674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 699f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 700f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 701f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 702f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 703727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 7040e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 705f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 70670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7076e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 70881d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 7090369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 7108b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 7118b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 71281d14e9dSStefano Zampini ierr = PetscFree2(pcbddc->B0_cols,pcbddc->B0_vals);CHKERRQ(ierr); 713674ae819SStefano Zampini PetscFunctionReturn(0); 714674ae819SStefano Zampini } 715674ae819SStefano Zampini 716674ae819SStefano Zampini #undef __FUNCT__ 717f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 718f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 7196bfb1811SStefano Zampini { 7206bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7216bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 7226bfb1811SStefano Zampini VecType impVecType; 723019a44ceSStefano Zampini PetscInt n_constraints,n_R,old_size,n_benign; 7246bfb1811SStefano Zampini PetscErrorCode ierr; 7256bfb1811SStefano Zampini 7266bfb1811SStefano Zampini PetscFunctionBegin; 727f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 728019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 729f4ddd8eeSStefano Zampini } 730e7b262bdSStefano Zampini /* get sizes */ 731c9ed8603SStefano Zampini n_benign = 0; 732c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) n_benign = 1; 733019a44ceSStefano Zampini n_constraints = pcbddc->local_primal_size - n_benign - pcbddc->n_vertices; 734b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 7356bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 736e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 737e7b262bdSStefano Zampini /* R nodes */ 738e7b262bdSStefano Zampini old_size = -1; 739e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 740e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 741e7b262bdSStefano Zampini } 742e7b262bdSStefano Zampini if (n_R != old_size) { 743e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 744e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 7456bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 7466bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 7476bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 7486bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 749e7b262bdSStefano Zampini } 750e7b262bdSStefano Zampini /* local primal dofs */ 751e7b262bdSStefano Zampini old_size = -1; 752e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 753e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 754e7b262bdSStefano Zampini } 755e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 756e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 75783b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 758e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 7596bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 760e7b262bdSStefano Zampini } 761e7b262bdSStefano Zampini /* local explicit constraints */ 762e7b262bdSStefano Zampini old_size = -1; 763e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 764e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 765e7b262bdSStefano Zampini } 766e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 767e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 76883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 76983b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 77083b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 77183b7ccabSStefano Zampini } 7726bfb1811SStefano Zampini PetscFunctionReturn(0); 7736bfb1811SStefano Zampini } 7746bfb1811SStefano Zampini 7756bfb1811SStefano Zampini #undef __FUNCT__ 77647f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 77747f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 77888ebb749SStefano Zampini { 77925084f0cSStefano Zampini PetscErrorCode ierr; 78025084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 78188ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 78288ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 783d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 78425084f0cSStefano Zampini /* submatrices of local problem */ 78580677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 786019a44ceSStefano Zampini /* submatrices of benign trick */ 787d16cbb6bSStefano Zampini Mat B0_V = NULL; 78806656605SStefano Zampini /* submatrices of local coarse problem */ 78906656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 79025084f0cSStefano Zampini /* working matrices */ 79106656605SStefano Zampini Mat C_CR; 79225084f0cSStefano Zampini /* additional working stuff */ 79306656605SStefano Zampini PC pc_R; 794d12edf2fSStefano Zampini Mat F,B0 = NULL; 79506656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 79606656605SStefano Zampini 79725084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 79806656605SStefano Zampini PetscScalar *work; 79906656605SStefano Zampini PetscInt *idx_V_B; 800d12edf2fSStefano Zampini PetscInt n,n_vertices,n_constraints,n_benign,p0_lidx_I = 0; 80106656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 802b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 80345a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 80488ebb749SStefano Zampini MatType impMatType; 80525084f0cSStefano Zampini /* some shortcuts to scalars */ 80606656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 80788ebb749SStefano Zampini 80888ebb749SStefano Zampini PetscFunctionBegin; 809c9ed8603SStefano Zampini n_benign = 0; 810c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) n_benign = 1; 811b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 812019a44ceSStefano Zampini n_constraints = pcbddc->local_primal_size - n_benign - n_vertices; 81388ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 814b371cd4fSStefano Zampini n_B = pcis->n_B; 815b371cd4fSStefano Zampini n_D = pcis->n - n_B; 81688ebb749SStefano Zampini n_R = pcis->n - n_vertices; 81788ebb749SStefano Zampini 81888ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 81988ebb749SStefano Zampini impMatType = MATSEQDENSE; 82088ebb749SStefano Zampini 82188ebb749SStefano Zampini /* vertices in boundary numbering */ 822785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 8230e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 82488ebb749SStefano Zampini if (i != n_vertices) { 82522d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 82688ebb749SStefano Zampini } 82788ebb749SStefano Zampini 82806656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 829019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 83006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 83106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 83206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 83306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 83406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 83506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 83606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 83706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 83806656605SStefano Zampini 83906656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 84006656605SStefano Zampini /* allocate workspace */ 84106656605SStefano Zampini n = 0; 84206656605SStefano Zampini if (n_constraints) { 84306656605SStefano Zampini n += n_R*n_constraints; 84406656605SStefano Zampini } 84506656605SStefano Zampini if (n_vertices) { 84606656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 84780677318SStefano Zampini n = PetscMax((n_R+n_B)*n_vertices,n); 84806656605SStefano Zampini } 8493301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 85006656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 85106656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 85206656605SStefano Zampini } 85306656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 85406656605SStefano Zampini 85506656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 85606656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 85706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 85806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 85906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 86006656605SStefano Zampini if (isLU || isILU || isCHOL) { 86106656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 862d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 863d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 864d62866d3SStefano Zampini MatFactorType type; 865d62866d3SStefano Zampini 8666816873aSStefano Zampini F = reuse_mumps->F; 8676816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 868d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 86906656605SStefano Zampini } else { 87006656605SStefano Zampini F = NULL; 87106656605SStefano Zampini } 87206656605SStefano Zampini 87388ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 87488ebb749SStefano Zampini if (n_constraints) { 87506656605SStefano Zampini Mat M1,M2,M3; 87680677318SStefano Zampini Mat auxmat; 87706656605SStefano Zampini IS is_aux; 87880677318SStefano Zampini PetscScalar *array,*array2; 87906656605SStefano Zampini 880f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 88180677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 88288ebb749SStefano Zampini 88325084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 88425084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 8858ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 88680677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 88788ebb749SStefano Zampini 88880677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 88980677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 89006656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 89188ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 89206656605SStefano Zampini const PetscScalar *row_cmat_values; 89306656605SStefano Zampini const PetscInt *row_cmat_indices; 89406656605SStefano Zampini PetscInt size_of_constraint,j; 89588ebb749SStefano Zampini 89606656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 89706656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 89806656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 89906656605SStefano Zampini } 90006656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 90106656605SStefano Zampini } 90280677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 90306656605SStefano Zampini if (F) { 90406656605SStefano Zampini Mat B; 90506656605SStefano Zampini 90606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 90780677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 90806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 90906656605SStefano Zampini } else { 91080677318SStefano Zampini PetscScalar *marr; 91180677318SStefano Zampini 91280677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 91306656605SStefano Zampini for (i=0;i<n_constraints;i++) { 91406656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 91580677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*n_R);CHKERRQ(ierr); 91606656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 91706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 91806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 91906656605SStefano Zampini } 92080677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 92106656605SStefano Zampini } 92280677318SStefano Zampini if (!pcbddc->switch_static) { 92380677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 92480677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 92580677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 92680677318SStefano Zampini for (i=0;i<n_constraints;i++) { 92780677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*n_R);CHKERRQ(ierr); 92880677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 92980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 93080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 93180677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 93280677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 93380677318SStefano Zampini } 93480677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 93580677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 93680677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 93780677318SStefano Zampini } else { 93880677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 93980677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 94025084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 94180677318SStefano Zampini } 94280677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 94380677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 94480677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 94506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 94606656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 94780677318SStefano Zampini if (isCHOL) { 94880677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 94980677318SStefano Zampini } else { 95025084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 95180677318SStefano Zampini } 95280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 95306656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 95425084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 95525084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 95625084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 95780677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 95880677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 95980677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 96006656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 96106656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 962f4ddd8eeSStefano Zampini } 96388ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 964d16cbb6bSStefano Zampini if (n_benign) { 965d16cbb6bSStefano Zampini IS dummy; 966d16cbb6bSStefano Zampini Mat B0_R; 967d16cbb6bSStefano Zampini PetscReal norm; 968d16cbb6bSStefano Zampini PetscInt ii[2]; 969d16cbb6bSStefano Zampini 970d16cbb6bSStefano Zampini ii[0] = 0; 971d16cbb6bSStefano Zampini ii[1] = pcbddc->B0_ncol; 972d16cbb6bSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,1,pcis->n,ii,pcbddc->B0_cols,pcbddc->B0_vals,&B0);CHKERRQ(ierr); 973d16cbb6bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&dummy);CHKERRQ(ierr); 974d16cbb6bSStefano Zampini ierr = MatGetSubMatrix(B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 975d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 976d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 977d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 978d16cbb6bSStefano Zampini } 979d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 980d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 981d16cbb6bSStefano Zampini } 982d16cbb6bSStefano Zampini 98388ebb749SStefano Zampini if (n_vertices) { 98406656605SStefano Zampini IS is_aux; 9853a50541eSStefano Zampini 9866816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 9876816873aSStefano Zampini IS tis; 9886816873aSStefano Zampini 9896816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 9906816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 9916816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 9926816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 9936816873aSStefano Zampini } else { 9943a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 9956816873aSStefano Zampini } 9969577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 9979577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 99804708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 999019a44ceSStefano Zampini if (n_benign) { 1000019a44ceSStefano Zampini IS dummy; 1001019a44ceSStefano Zampini 1002019a44ceSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&dummy);CHKERRQ(ierr); 1003019a44ceSStefano Zampini ierr = MatGetSubMatrix(B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1004019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1005019a44ceSStefano Zampini } 100625084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 100788ebb749SStefano Zampini } 100888ebb749SStefano Zampini 100988ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1010f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 101106656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 101206656605SStefano Zampini if (pcbddc->coarse_phi_D) { 101306656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 101406656605SStefano Zampini } 1015f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 101606656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 101706656605SStefano Zampini PetscScalar *marray; 101806656605SStefano Zampini 101906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 102006656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1021f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1022f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1023f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1024f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1025f4ddd8eeSStefano Zampini } 1026f4ddd8eeSStefano Zampini } 102706656605SStefano Zampini 1028f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 102906656605SStefano Zampini PetscScalar *marray; 103088ebb749SStefano Zampini 103106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 10328eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 103306656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 103488ebb749SStefano Zampini } 10353301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 103606656605SStefano Zampini n *= 2; 103788ebb749SStefano Zampini } 103806656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 103906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 104006656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 10418eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 104206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 104306656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 104488ebb749SStefano Zampini } 10453301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 104606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 10478eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 104806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 104906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 105088ebb749SStefano Zampini } 105188ebb749SStefano Zampini } else { 1052c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1053c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 10541b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1055c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1056c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1057c0553b1fSStefano Zampini } 105888ebb749SStefano Zampini } 105906656605SStefano Zampini } 1060019a44ceSStefano Zampini 106106656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 1062d12edf2fSStefano Zampini if (n_benign && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1063d12edf2fSStefano Zampini const PetscInt *idxs; 1064d12edf2fSStefano Zampini 1065d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1066d12edf2fSStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx,pcis->n-pcis->n_B,idxs,&p0_lidx_I);CHKERRQ(ierr); 1067d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1068d12edf2fSStefano Zampini } 1069d16cbb6bSStefano Zampini 107006656605SStefano Zampini /* vertices */ 107106656605SStefano Zampini if (n_vertices) { 107216f15bc4SStefano Zampini 107304708bb6SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 107404708bb6SStefano Zampini 107516f15bc4SStefano Zampini if (n_R) { 107606656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 107706656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 107816f15bc4SStefano Zampini PetscScalar *x,*y; 107904708bb6SStefano Zampini PetscBool isseqaij; 108006656605SStefano Zampini 108121eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 108206656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 108304708bb6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 10846816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 108506656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 108606656605SStefano Zampini } else { 108706656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 108806656605SStefano Zampini for (i=0;i<n_vertices;i++) { 108906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 109006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 109106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 109206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 109306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 109406656605SStefano Zampini } 109506656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 109606656605SStefano Zampini } 109780677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 109806656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 109906656605SStefano Zampini if (n_constraints) { 110006656605SStefano Zampini Mat B; 110180677318SStefano Zampini 1102b3d85658SStefano Zampini ierr = PetscMemzero(work+n_R*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 110380677318SStefano Zampini for (i=0;i<n_vertices;i++) { 110480677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 110580677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+n_R*n_vertices+i*n_B);CHKERRQ(ierr); 110680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 110780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 110880677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 110980677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 111080677318SStefano Zampini } 111180677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 111280677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 111380677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 111406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 111580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 111606656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 111706656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 111806656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 111906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 112006656605SStefano Zampini } 112104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 112204708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 112304708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 112404708bb6SStefano Zampini } 112506656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 112680677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 112706656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 112806656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 112906656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 113006656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 113106656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 113206656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 113306656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1134d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1135019a44ceSStefano Zampini } else { 1136d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1137d16cbb6bSStefano Zampini } 1138d16cbb6bSStefano Zampini if (n_benign) { 1139019a44ceSStefano Zampini const PetscScalar *vals; 1140019a44ceSStefano Zampini const PetscInt *idxs; 1141019a44ceSStefano Zampini PetscInt n,j; 1142019a44ceSStefano Zampini 1143019a44ceSStefano Zampini ierr = MatGetRow(B0_V,0,&n,&idxs,&vals);CHKERRQ(ierr); 1144d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 1145d16cbb6bSStefano Zampini coarse_submat_vals[(pcbddc->local_primal_size-1)*pcbddc->local_primal_size+idxs[j]] = vals[j]; 1146d16cbb6bSStefano Zampini coarse_submat_vals[(idxs[j]+1)*pcbddc->local_primal_size-1] = vals[j]; 1147019a44ceSStefano Zampini } 1148019a44ceSStefano Zampini ierr = MatRestoreRow(B0_V,0,&n,&idxs,&vals);CHKERRQ(ierr); 114916f15bc4SStefano Zampini } 115021eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1151d16cbb6bSStefano Zampini 115206656605SStefano Zampini /* coarse basis functions */ 115306656605SStefano Zampini for (i=0;i<n_vertices;i++) { 115416f15bc4SStefano Zampini PetscScalar *y; 115516f15bc4SStefano Zampini 115606656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 115706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 115806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 115906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 116006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 116106656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 116206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 116306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 116406656605SStefano Zampini 116506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 116606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 116706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 116806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 116906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 117006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 1171a0aff763SStefano Zampini if (n_benign) y[n_D*i+p0_lidx_I] = 0.0; 117206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 117306656605SStefano Zampini } 117406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 117506656605SStefano Zampini } 117604708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 117704708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 117806656605SStefano Zampini } 117906656605SStefano Zampini 118006656605SStefano Zampini if (n_constraints) { 118106656605SStefano Zampini Mat B; 118206656605SStefano Zampini 118306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 118406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 118580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 118606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 118706656605SStefano Zampini if (n_vertices) { 118880677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 118980677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 119080677318SStefano Zampini } else { 119180677318SStefano Zampini Mat S_VCt; 119280677318SStefano Zampini 119380677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 119480677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 119580677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 119680677318SStefano Zampini } 119706656605SStefano Zampini } 119806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 119906656605SStefano Zampini /* coarse basis functions */ 120006656605SStefano Zampini for (i=0;i<n_constraints;i++) { 120106656605SStefano Zampini PetscScalar *y; 120206656605SStefano Zampini 120306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 120406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 120506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 120606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 120706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 120806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 120906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 121006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 121106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 121206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 121306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 121406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 121506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 1216d16cbb6bSStefano Zampini if (n_benign) y[n_D*(i+n_vertices)+p0_lidx_I] = 0.0; 121706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 121806656605SStefano Zampini } 121906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 122006656605SStefano Zampini } 122106656605SStefano Zampini } 122280677318SStefano Zampini if (n_constraints) { 122380677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 122480677318SStefano Zampini } 122506656605SStefano Zampini 1226019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1227019a44ceSStefano Zampini 122806656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 12293301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 123006656605SStefano Zampini 123106656605SStefano Zampini if (n_constraints) { 123216f15bc4SStefano Zampini Mat S_CCT,B_C; 123306656605SStefano Zampini 123480677318SStefano Zampini /* this is a lazy thing */ 123580677318SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 123606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 123706656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 123806656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 123916f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 124006656605SStefano Zampini if (n_vertices) { 124116f15bc4SStefano Zampini Mat B_V,S_VCT; 124206656605SStefano Zampini 124306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 124406656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 124506656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 124606656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 124716f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 124806656605SStefano Zampini } 124906656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 125080677318SStefano Zampini } else { /* if there are no constraints, reset work */ 125180677318SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 125206656605SStefano Zampini } 125316f15bc4SStefano Zampini if (n_vertices && n_R) { 125406656605SStefano Zampini Mat A_VRT; 125580677318SStefano Zampini PetscScalar *marray; 125606656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 125706656605SStefano Zampini 125880677318SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_VRT);CHKERRQ(ierr); 125980677318SStefano Zampini ierr = MatConvert(A_VRT,impMatType,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 126080677318SStefano Zampini ierr = MatDenseGetArray(A_VRT,&marray);CHKERRQ(ierr); 126106656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 126280677318SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,marray,&B_one,work,&B_one)); 126380677318SStefano Zampini ierr = MatDenseRestoreArray(A_VRT,&marray);CHKERRQ(ierr); 126416f15bc4SStefano Zampini ierr = MatDestroy(&A_VRT);CHKERRQ(ierr); 126506656605SStefano Zampini } 126606656605SStefano Zampini 126706656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 126806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 126906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 127006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 127106656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 127206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 127306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 127406656605SStefano Zampini } 127506656605SStefano Zampini } else { 127606656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 127706656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 127806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 127906656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 128006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 128106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 128206656605SStefano Zampini } 128306656605SStefano Zampini } 128406656605SStefano Zampini /* coarse basis functions */ 128506656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 128606656605SStefano Zampini PetscScalar *y; 128706656605SStefano Zampini 128806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 128906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 129006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 129106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 129206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 129306656605SStefano Zampini if (i<n_vertices) { 129406656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 129506656605SStefano Zampini } 129606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 129706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 129806656605SStefano Zampini 129906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 130006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 130106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 130206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 130306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 130406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 130506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 130606656605SStefano Zampini } 130706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 130806656605SStefano Zampini } 130906656605SStefano Zampini } 1310d62866d3SStefano Zampini /* free memory */ 131188ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 131206656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 131306656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 131406656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 131506656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 1316d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1317d62866d3SStefano Zampini if (n_vertices) { 1318d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1319d62866d3SStefano Zampini } 1320d62866d3SStefano Zampini if (n_constraints) { 1321d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 1322d62866d3SStefano Zampini } 132388ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 132488ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 132588ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1326d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 132788ebb749SStefano Zampini Mat coarse_sub_mat; 132825084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 132988ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 133088ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 133188ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 13328bec7fa6SStefano Zampini Mat C_B,CPHI; 13338bec7fa6SStefano Zampini IS is_dummy; 13348bec7fa6SStefano Zampini Vec mones; 133588ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 133688ebb749SStefano Zampini PetscReal real_value; 133788ebb749SStefano Zampini 133888ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 133988ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 134088ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 134188ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 134288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 134388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1344c0553b1fSStefano Zampini if (unsymmetric_check) { 134588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 134688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 134788ebb749SStefano Zampini } 134888ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 134988ebb749SStefano Zampini 135025084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 13513301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 135225084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1353c0553b1fSStefano Zampini if (unsymmetric_check) { 135488ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 135588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 135688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 135788ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 135888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 135988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 136088ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 136188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 136288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 136388ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 136488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 136588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 136688ebb749SStefano Zampini } else { 136788ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 136888ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 136988ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 137088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 137188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 137288ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 137388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 137488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 137588ebb749SStefano Zampini } 137688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 137788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 137888ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 137988ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 1380d12edf2fSStefano Zampini if (n_benign) { 1381d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 1382d12edf2fSStefano Zampini PetscScalar *data,*data2; 1383d12edf2fSStefano Zampini 1384d12edf2fSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&is_dummy);CHKERRQ(ierr); 1385d12edf2fSStefano Zampini ierr = MatGetSubMatrix(B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 1386d12edf2fSStefano Zampini ierr = MatGetSubMatrix(B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 1387d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 1388d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 1389d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 1390d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 1391d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1392d16cbb6bSStefano Zampini data[(pcbddc->local_primal_size-1)*pcbddc->local_primal_size+i] += data2[i]; 1393d16cbb6bSStefano Zampini data[(i+1)*pcbddc->local_primal_size-1] += data2[i]; 1394d12edf2fSStefano Zampini } 1395d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 1396d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 1397d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 1398d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 1399d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 1400d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 1401d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 1402d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1403d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 1404d12edf2fSStefano Zampini } 1405d12edf2fSStefano Zampini #if 0 1406d12edf2fSStefano Zampini { 1407d12edf2fSStefano Zampini PetscViewer viewer; 1408d12edf2fSStefano Zampini char filename[256]; 1409d12edf2fSStefano Zampini sprintf(filename,"proj_local_coarse_mat%d.m",PetscGlobalRank); 1410d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1411d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1412d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 1413d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1414d12edf2fSStefano Zampini } 1415d12edf2fSStefano Zampini #endif 141681d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 14178bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 14180fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 141906656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 14208bec7fa6SStefano Zampini 14218bec7fa6SStefano Zampini /* check constraints */ 1422d12edf2fSStefano Zampini if (!n_benign) { 14238bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 14248bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 14258bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 14268bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 14278bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 14288bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 14298bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1430bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 1431c0553b1fSStefano Zampini if (unsymmetric_check) { 1432bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 1433bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 1434bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 1435bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1436bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 143788ebb749SStefano Zampini } 14388bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 14398bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 14408bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 14418bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 1442d12edf2fSStefano Zampini } 144325084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 144488ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 144588ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 144688ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 144788ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 144888ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 144988ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 145088ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 145188ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 145288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 145388ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 1454c0553b1fSStefano Zampini if (unsymmetric_check) { 145588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 145688ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 145788ebb749SStefano Zampini } 145888ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 145988ebb749SStefano Zampini } 1460d12edf2fSStefano Zampini ierr = MatDestroy(&B0);CHKERRQ(ierr); 14618629588bSStefano Zampini /* get back data */ 14628629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 146388ebb749SStefano Zampini PetscFunctionReturn(0); 146488ebb749SStefano Zampini } 146588ebb749SStefano Zampini 146688ebb749SStefano Zampini #undef __FUNCT__ 1467d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1468d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 1469aa0d41d4SStefano Zampini { 1470d65f70fdSStefano Zampini Mat *work_mat; 1471d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1472d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1473d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1474aa0d41d4SStefano Zampini PetscErrorCode ierr; 1475aa0d41d4SStefano Zampini 1476aa0d41d4SStefano Zampini PetscFunctionBegin; 1477d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1478d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1479d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1480d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1481aa0d41d4SStefano Zampini 1482d65f70fdSStefano Zampini if (!rsorted) { 1483906d46d4SStefano Zampini const PetscInt *idxs; 1484906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 1485aa0d41d4SStefano Zampini 1486d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1487d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1488d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1489d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1490aa0d41d4SStefano Zampini } 1491d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1492d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1493d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1494d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1495aa0d41d4SStefano Zampini } 1496d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1497d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1498d65f70fdSStefano Zampini } else { 1499d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1500d65f70fdSStefano Zampini isrow_s = isrow; 1501aa0d41d4SStefano Zampini } 1502906d46d4SStefano Zampini 1503d65f70fdSStefano Zampini if (!csorted) { 1504d65f70fdSStefano Zampini if (isrow == iscol) { 1505d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1506d65f70fdSStefano Zampini iscol_s = isrow_s; 1507d65f70fdSStefano Zampini } else { 1508d65f70fdSStefano Zampini const PetscInt *idxs; 1509d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1510906d46d4SStefano Zampini 1511d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1512d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1513d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1514d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1515d65f70fdSStefano Zampini } 1516d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1517d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1518d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1519d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1520d65f70fdSStefano Zampini } 1521d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1522d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1523d65f70fdSStefano Zampini } 1524d65f70fdSStefano Zampini } else { 1525d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1526d65f70fdSStefano Zampini iscol_s = iscol; 1527d65f70fdSStefano Zampini } 1528d65f70fdSStefano Zampini 1529d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1530d65f70fdSStefano Zampini 1531d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1532906d46d4SStefano Zampini Mat new_mat; 1533d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1534906d46d4SStefano Zampini 1535d65f70fdSStefano Zampini if (!rsorted) { 1536d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1537d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1538d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1539d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1540906d46d4SStefano Zampini } 1541d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1542d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1543d65f70fdSStefano Zampini } else { 1544d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1545906d46d4SStefano Zampini } 1546d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1547d65f70fdSStefano Zampini 1548d65f70fdSStefano Zampini if (!csorted) { 1549d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1550d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1551d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1552d65f70fdSStefano Zampini } else { 1553d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1554d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1555d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1556d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1557d65f70fdSStefano Zampini } 1558d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1559d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1560d65f70fdSStefano Zampini } 1561d65f70fdSStefano Zampini } else { 1562d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1563d65f70fdSStefano Zampini } 1564d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1565d65f70fdSStefano Zampini 1566d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1567d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1568d65f70fdSStefano Zampini work_mat[0] = new_mat; 1569d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1570d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1571d65f70fdSStefano Zampini } 1572d65f70fdSStefano Zampini 1573d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1574d65f70fdSStefano Zampini *B = work_mat[0]; 1575d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1576d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1577d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1578d65f70fdSStefano Zampini PetscFunctionReturn(0); 1579d65f70fdSStefano Zampini } 1580d65f70fdSStefano Zampini 1581d65f70fdSStefano Zampini #undef __FUNCT__ 15825e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 15835e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1584aa0d41d4SStefano Zampini { 1585aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 15865e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1587d65f70fdSStefano Zampini Mat new_mat; 15885e8657edSStefano Zampini IS is_local,is_global; 1589d65f70fdSStefano Zampini PetscInt local_size; 1590d65f70fdSStefano Zampini PetscBool isseqaij; 1591aa0d41d4SStefano Zampini PetscErrorCode ierr; 1592aa0d41d4SStefano Zampini 1593aa0d41d4SStefano Zampini PetscFunctionBegin; 1594aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 15955e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 15965e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1597b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 1598aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1599d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 1600aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1601906d46d4SStefano Zampini 1602906d46d4SStefano Zampini /* check */ 1603906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1604906d46d4SStefano Zampini Vec x,x_change; 1605906d46d4SStefano Zampini PetscReal error; 1606906d46d4SStefano Zampini 16075e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1608906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 16095e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 1610e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1611e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1612d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 1613e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1614e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1615906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1616906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1617906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1618906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1619906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1620906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1621906d46d4SStefano Zampini } 1622906d46d4SStefano Zampini 162322d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 16249b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 162522d5777bSStefano Zampini if (isseqaij) { 1626d65f70fdSStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1627aa0d41d4SStefano Zampini } else { 1628aa0d41d4SStefano Zampini Mat work_mat; 1629aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1630d65f70fdSStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1631aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1632aa0d41d4SStefano Zampini } 16333301b35fSStefano Zampini if (matis->A->symmetric_set) { 16343301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 1635e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 16363301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 1637e496cd5dSStefano Zampini #endif 16383301b35fSStefano Zampini } 163945a1bb75SStefano Zampini /* 164045a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1641d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 164245a1bb75SStefano Zampini */ 1643d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1644aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1645aa0d41d4SStefano Zampini } 1646aa0d41d4SStefano Zampini 1647aa0d41d4SStefano Zampini #undef __FUNCT__ 1648a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 16498ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 1650a64d13efSStefano Zampini { 1651a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1652a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1653d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 165453892102SStefano Zampini PetscInt *idx_R_local=NULL; 16553a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 16563a50541eSStefano Zampini PetscInt vbs,bs; 16576816873aSStefano Zampini PetscBT bitmask=NULL; 1658a64d13efSStefano Zampini PetscErrorCode ierr; 1659a64d13efSStefano Zampini 1660a64d13efSStefano Zampini PetscFunctionBegin; 1661b23d619eSStefano Zampini /* 1662b23d619eSStefano Zampini No need to setup local scatters if 1663b23d619eSStefano Zampini - primal space is unchanged 1664b23d619eSStefano Zampini AND 1665b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 1666b23d619eSStefano Zampini AND 1667b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 1668b23d619eSStefano Zampini */ 1669b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 1670f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 1671f4ddd8eeSStefano Zampini } 1672f4ddd8eeSStefano Zampini /* destroy old objects */ 1673f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1674f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1675f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1676a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 1677b371cd4fSStefano Zampini n_B = pcis->n_B; 1678b371cd4fSStefano Zampini n_D = pcis->n - n_B; 1679b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 16803a50541eSStefano Zampini 1681a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 16826816873aSStefano Zampini 168353892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 16846816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 1685854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 1686a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 1687a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 16880e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 1689a64d13efSStefano Zampini } 1690a64d13efSStefano Zampini 1691a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 16924641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 16936816873aSStefano Zampini idx_R_local[n_R++] = i; 1694a64d13efSStefano Zampini } 1695a64d13efSStefano Zampini } 169653892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 16976816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 16986816873aSStefano Zampini 169953892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 170053892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 17016816873aSStefano Zampini } 17023a50541eSStefano Zampini 17033a50541eSStefano Zampini /* Block code */ 17043a50541eSStefano Zampini vbs = 1; 17053a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 17063a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 17073a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 17083a50541eSStefano Zampini PetscInt *vary; 1709d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 1710785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 17113a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 1712d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 1713d3df7717SStefano Zampini /* it is ok to check this way since local_primal_ref_node are always sorted by local numbering and idx_R_local is obtained as a complement */ 17140e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 1715d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 17163a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 17173a50541eSStefano Zampini is_blocked = PETSC_FALSE; 17183a50541eSStefano Zampini break; 17193a50541eSStefano Zampini } 17203a50541eSStefano Zampini } 1721d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 1722d3df7717SStefano Zampini } else { 1723d3df7717SStefano Zampini /* Verify directly the R set */ 1724d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 1725d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 1726d3df7717SStefano Zampini for (j=1; j<bs; j++) { 1727d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 1728d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 1729d3df7717SStefano Zampini break; 1730d3df7717SStefano Zampini } 1731d3df7717SStefano Zampini } 1732d3df7717SStefano Zampini } 1733d3df7717SStefano Zampini } 17343a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 17353a50541eSStefano Zampini vbs = bs; 17363a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 17373a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 17383a50541eSStefano Zampini } 17393a50541eSStefano Zampini } 17403a50541eSStefano Zampini } 17413a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 174253892102SStefano Zampini if (sub_schurs->reuse_mumps) { 174353892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 174453892102SStefano Zampini 174553892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 174653892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 174753892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 174853892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 174953892102SStefano Zampini } else { 17503a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 175153892102SStefano Zampini } 1752a64d13efSStefano Zampini 1753a64d13efSStefano Zampini /* print some info if requested */ 1754a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 1755c9ed8603SStefano Zampini PetscInt benign = 0; 1756019a44ceSStefano Zampini 1757c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) benign = 1; 1758a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1759a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 17600fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1761a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 1762a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 1763019a44ceSStefano 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-benign,pcbddc->local_primal_size);CHKERRQ(ierr); 1764a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1765a64d13efSStefano Zampini } 1766a64d13efSStefano Zampini 1767a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 17686816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 17696816873aSStefano Zampini IS is_aux1,is_aux2; 17706816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 17716816873aSStefano Zampini 17723a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1773854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 1774854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 1775a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 17764641a718SStefano Zampini for (i=0; i<n_D; i++) { 17774641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 17784641a718SStefano Zampini } 1779a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1780a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 17814641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 17824641a718SStefano Zampini aux_array1[j++] = i; 1783a64d13efSStefano Zampini } 1784a64d13efSStefano Zampini } 1785a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1786a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1787a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 17884641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 17894641a718SStefano Zampini aux_array2[j++] = i; 1790a64d13efSStefano Zampini } 1791a64d13efSStefano Zampini } 1792a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1793a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 1794a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 1795a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1796a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 1797a64d13efSStefano Zampini 17988eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1799785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 1800a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 18014641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 18024641a718SStefano Zampini aux_array1[j++] = i; 1803a64d13efSStefano Zampini } 1804a64d13efSStefano Zampini } 1805a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1806a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 1807a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1808a64d13efSStefano Zampini } 18094641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 18103a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1811d62866d3SStefano Zampini } else { 181253892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 18136816873aSStefano Zampini IS tis; 18146816873aSStefano Zampini PetscInt schur_size; 18156816873aSStefano Zampini 181653892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 18176816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 181853892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 18196816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 18206816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 18216816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 18226816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 18236816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 1824d62866d3SStefano Zampini } 1825d62866d3SStefano Zampini } 1826a64d13efSStefano Zampini PetscFunctionReturn(0); 1827a64d13efSStefano Zampini } 1828a64d13efSStefano Zampini 1829304d26faSStefano Zampini 1830304d26faSStefano Zampini #undef __FUNCT__ 1831304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 1832684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 1833304d26faSStefano Zampini { 1834304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1835304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1836304d26faSStefano Zampini PC pc_temp; 1837304d26faSStefano Zampini Mat A_RR; 1838f4ddd8eeSStefano Zampini MatReuse reuse; 1839304d26faSStefano Zampini PetscScalar m_one = -1.0; 1840304d26faSStefano Zampini PetscReal value; 184104708bb6SStefano Zampini PetscInt n_D,n_R; 18429577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 1843304d26faSStefano Zampini PetscErrorCode ierr; 1844e604994aSStefano Zampini /* prefixes stuff */ 1845312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 1846e604994aSStefano Zampini size_t len; 1847304d26faSStefano Zampini 1848304d26faSStefano Zampini PetscFunctionBegin; 1849304d26faSStefano Zampini 1850e604994aSStefano Zampini /* compute prefixes */ 1851e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 1852e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 1853e604994aSStefano Zampini if (!pcbddc->current_level) { 1854e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1855e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1856e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1857e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1858e604994aSStefano Zampini } else { 1859e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 1860312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 1861e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 1862e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 1863312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 1864312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 186534d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 186634d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 1867e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1868e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1869e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 1870e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 1871e604994aSStefano Zampini } 1872e604994aSStefano Zampini 1873304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 1874684f6988SStefano Zampini if (dirichlet) { 1875d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 18763301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 18773301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 1878964fefecSStefano Zampini } 1879ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 1880964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 1881304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 1882304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 1883304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 1884304d26faSStefano Zampini /* default */ 1885304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1886e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 18879577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1888304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 18899577ea80SStefano Zampini if (issbaij) { 18909577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 18919577ea80SStefano Zampini } else { 1892304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 18939577ea80SStefano Zampini } 1894304d26faSStefano Zampini /* Allow user's customization */ 1895304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1896304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1897304d26faSStefano Zampini } 1898d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 1899d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 1900d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1901d62866d3SStefano Zampini 1902d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 1903d5574798SStefano Zampini } 1904304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1905304d26faSStefano Zampini if (!n_D) { 1906304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 1907304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1908304d26faSStefano Zampini } 1909304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 1910304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1911304d26faSStefano Zampini /* set ksp_D into pcis data */ 1912304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 1913304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 1914304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 1915684f6988SStefano Zampini } 1916304d26faSStefano Zampini 1917304d26faSStefano Zampini /* NEUMANN PROBLEM */ 1918684f6988SStefano Zampini A_RR = 0; 1919684f6988SStefano Zampini if (neumann) { 1920d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 192104708bb6SStefano Zampini PetscInt ibs,mbs; 192204708bb6SStefano Zampini PetscBool issbaij; 192304708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1924f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 19258ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 1926f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 1927f4ddd8eeSStefano Zampini PetscInt nn_R; 192881d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 1929f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1930f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 1931f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 1932f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 1933f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1934f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1935f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 1936727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 1937f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1938f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1939f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 1940f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 1941f4ddd8eeSStefano Zampini } 1942f4ddd8eeSStefano Zampini } 1943f4ddd8eeSStefano Zampini /* last check */ 1944d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 1945f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1946f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1947f4ddd8eeSStefano Zampini } 1948f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 1949f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1950f4ddd8eeSStefano Zampini } 1951f4ddd8eeSStefano Zampini /* extract A_RR */ 1952af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 1953af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 195404708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 195504708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 195604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 195704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 195804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 1959af732b37SStefano Zampini } else { 196004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 19616816873aSStefano Zampini } 196204708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 196304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 196404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 196504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 196604708bb6SStefano Zampini } else { 196704708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 196804708bb6SStefano Zampini } 196904708bb6SStefano Zampini } 197004708bb6SStefano Zampini if (!sub_schurs->reuse_mumps) { 1971f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 19723301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 19733301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 19746816873aSStefano Zampini } 19756816873aSStefano Zampini } else { 19766816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 19776816873aSStefano Zampini 19786816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 19796816873aSStefano Zampini ierr = PCGetOperators(reuse_mumps->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 19806816873aSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1981af732b37SStefano Zampini } 1982f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 1983304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 1984304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 1985304d26faSStefano Zampini /* default */ 1986304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1987e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 1988304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 19899577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 19909577ea80SStefano Zampini if (issbaij) { 19919577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 19929577ea80SStefano Zampini } else { 1993304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 19949577ea80SStefano Zampini } 1995304d26faSStefano Zampini /* Allow user's customization */ 1996304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1997304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1998304d26faSStefano Zampini } 1999d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2000304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2001304d26faSStefano Zampini if (!n_R) { 2002304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2003304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2004304d26faSStefano Zampini } 2005d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 2006d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2007d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2008d62866d3SStefano Zampini 2009d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 2010d62866d3SStefano Zampini } 2011304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2012304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2013684f6988SStefano Zampini } 20146816873aSStefano Zampini /* free Neumann problem's matrix */ 20156816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2016304d26faSStefano Zampini 2017304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 20180fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2019684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2020684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2021684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2022684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2023684f6988SStefano Zampini } 2024684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 20250fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 20260fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 20270fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 20280fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 20290fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2030304d26faSStefano Zampini /* need to be adapted? */ 2031b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2032b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2033b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2034304d26faSStefano Zampini /* print info */ 2035304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2036e604994aSStefano 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); 2037304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2038304d26faSStefano Zampini } 2039b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2040298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2041304d26faSStefano Zampini } 2042684f6988SStefano Zampini } 2043684f6988SStefano Zampini if (neumann) { /* Neumann */ 20446816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 20450fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 20460fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 20470fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 20480fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 20490fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2050304d26faSStefano Zampini /* need to be adapted? */ 2051b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2052b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2053304d26faSStefano Zampini /* print info */ 2054304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2055e604994aSStefano 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); 2056304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2057304d26faSStefano Zampini } 2058b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2059298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2060304d26faSStefano Zampini } 20610fccc4e9SStefano Zampini } 2062684f6988SStefano Zampini } 2063304d26faSStefano Zampini PetscFunctionReturn(0); 2064304d26faSStefano Zampini } 2065304d26faSStefano Zampini 2066304d26faSStefano Zampini #undef __FUNCT__ 2067ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 206880677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2069674ae819SStefano Zampini { 2070674ae819SStefano Zampini PetscErrorCode ierr; 2071674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2072be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2073674ae819SStefano Zampini 2074674ae819SStefano Zampini PetscFunctionBegin; 2075be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 207680677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 207720c7b377SStefano Zampini } 207880677318SStefano Zampini if (!pcbddc->switch_static) { 207980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 208080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 208180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 208220c7b377SStefano Zampini } 2083be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 208480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 208580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 208620c7b377SStefano Zampini } else { 2087be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2088be83ff47SStefano Zampini 208953892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 209053892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 209120c7b377SStefano Zampini } 2092be83ff47SStefano Zampini } else { 209380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 209480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 209580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 209680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 209780677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 209880677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 209980677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 210080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2102674ae819SStefano Zampini } 2103674ae819SStefano Zampini } 2104be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 210580677318SStefano Zampini if (applytranspose) { 210680677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 210780677318SStefano Zampini } else { 210880677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 210980677318SStefano Zampini } 211053892102SStefano Zampini #if defined(PETSC_HAVE_MUMPS) 2111be83ff47SStefano Zampini } else { 2112be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2113be83ff47SStefano Zampini 2114be83ff47SStefano Zampini if (applytranspose) { 211553892102SStefano Zampini ierr = MatMumpsSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2116be83ff47SStefano Zampini } else { 211753892102SStefano Zampini ierr = MatMumpsSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2118be83ff47SStefano Zampini } 211953892102SStefano Zampini #endif 2120be83ff47SStefano Zampini } 212180677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 212280677318SStefano Zampini if (!pcbddc->switch_static) { 2123be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 212480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 212580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2126be83ff47SStefano Zampini } else { 2127be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2128be83ff47SStefano Zampini 212953892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213053892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2131be83ff47SStefano Zampini } 213280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 213380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 213480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 213580677318SStefano Zampini } 213680677318SStefano Zampini } else { 213780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 214280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 214380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 214480677318SStefano Zampini } 214580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2149674ae819SStefano Zampini } 2150674ae819SStefano Zampini PetscFunctionReturn(0); 2151674ae819SStefano Zampini } 2152674ae819SStefano Zampini 2153dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2154674ae819SStefano Zampini #undef __FUNCT__ 2155674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2156dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2157674ae819SStefano Zampini { 2158674ae819SStefano Zampini PetscErrorCode ierr; 2159674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2160674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2161674ae819SStefano Zampini const PetscScalar zero = 0.0; 2162674ae819SStefano Zampini 2163674ae819SStefano Zampini PetscFunctionBegin; 2164dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2165dc359a40SStefano Zampini if (applytranspose) { 2166674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 21678eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2168dc359a40SStefano Zampini } else { 2169674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2170674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 217115aaf578SStefano Zampini } 2172efc2fbd9SStefano Zampini 2173efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 2174c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 2175efc2fbd9SStefano Zampini PetscScalar *array; 2176efc2fbd9SStefano Zampini 2177efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2178efc2fbd9SStefano Zampini array[pcbddc->local_primal_size-1] += pcbddc->benign_p0; 2179efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2180efc2fbd9SStefano Zampini } 2181efc2fbd9SStefano Zampini 218212edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 218312edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 218412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218612edc857SStefano Zampini 21879f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 218812edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 218912edc857SStefano Zampini if (pcbddc->coarse_ksp) { 2190964fefecSStefano Zampini Vec rhs,sol; 2191964fefecSStefano Zampini 2192964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2193964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 219412edc857SStefano Zampini if (applytranspose) { 2195964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 219612edc857SStefano Zampini } else { 2197964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 219812edc857SStefano Zampini } 219912edc857SStefano Zampini } 2200674ae819SStefano Zampini 2201674ae819SStefano Zampini /* Local solution on R nodes */ 220280677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 220380677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 22049f00e9b4SStefano Zampini } 2205674ae819SStefano Zampini 22069f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 22079f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 220812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2209674ae819SStefano Zampini 2210674ae819SStefano Zampini /* Sum contributions from two levels */ 2211dc359a40SStefano Zampini if (applytranspose) { 2212dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2213dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2214dc359a40SStefano Zampini } else { 2215674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 22168eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2217dc359a40SStefano Zampini } 2218efc2fbd9SStefano Zampini /* store p0 */ 2219c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 2220efc2fbd9SStefano Zampini PetscScalar *array; 2221efc2fbd9SStefano Zampini 2222efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2223efc2fbd9SStefano Zampini pcbddc->benign_p0 = array[pcbddc->local_primal_size-1]; 2224efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2225efc2fbd9SStefano Zampini } 2226674ae819SStefano Zampini PetscFunctionReturn(0); 2227674ae819SStefano Zampini } 2228674ae819SStefano Zampini 2229674ae819SStefano Zampini #undef __FUNCT__ 2230674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 223112edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2232674ae819SStefano Zampini { 2233674ae819SStefano Zampini PetscErrorCode ierr; 2234674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 223558da7f69SStefano Zampini PetscScalar *array; 223612edc857SStefano Zampini Vec from,to; 2237674ae819SStefano Zampini 2238674ae819SStefano Zampini PetscFunctionBegin; 223912edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 224012edc857SStefano Zampini from = pcbddc->coarse_vec; 224112edc857SStefano Zampini to = pcbddc->vec1_P; 224212edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 224312edc857SStefano Zampini Vec tvec; 224458da7f69SStefano Zampini 224558da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 224658da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 224712edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 224858da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 224958da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 225058da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 225112edc857SStefano Zampini } 225212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 225312edc857SStefano Zampini from = pcbddc->vec1_P; 225412edc857SStefano Zampini to = pcbddc->coarse_vec; 225512edc857SStefano Zampini } 225612edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 2257674ae819SStefano Zampini PetscFunctionReturn(0); 2258674ae819SStefano Zampini } 2259674ae819SStefano Zampini 2260674ae819SStefano Zampini #undef __FUNCT__ 2261674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 226212edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 2263674ae819SStefano Zampini { 2264674ae819SStefano Zampini PetscErrorCode ierr; 2265674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 226658da7f69SStefano Zampini PetscScalar *array; 226712edc857SStefano Zampini Vec from,to; 2268674ae819SStefano Zampini 2269674ae819SStefano Zampini PetscFunctionBegin; 227012edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 227112edc857SStefano Zampini from = pcbddc->coarse_vec; 227212edc857SStefano Zampini to = pcbddc->vec1_P; 227312edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 227412edc857SStefano Zampini from = pcbddc->vec1_P; 227512edc857SStefano Zampini to = pcbddc->coarse_vec; 227612edc857SStefano Zampini } 227712edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 227812edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 227912edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 228012edc857SStefano Zampini Vec tvec; 228158da7f69SStefano Zampini 228212edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 228358da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 228458da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 228558da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 228658da7f69SStefano Zampini } 228758da7f69SStefano Zampini } else { 228858da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 228958da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 229012edc857SStefano Zampini } 229112edc857SStefano Zampini } 2292674ae819SStefano Zampini PetscFunctionReturn(0); 2293674ae819SStefano Zampini } 2294674ae819SStefano Zampini 2295984c4197SStefano Zampini /* uncomment for testing purposes */ 2296984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 2297674ae819SStefano Zampini #undef __FUNCT__ 2298674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 2299674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 2300674ae819SStefano Zampini { 2301674ae819SStefano Zampini PetscErrorCode ierr; 2302674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2303674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2304674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2305984c4197SStefano Zampini /* one and zero */ 2306984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 2307984c4197SStefano Zampini /* space to store constraints and their local indices */ 23089162d606SStefano Zampini PetscScalar *constraints_data; 23099162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 23109162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 23119162d606SStefano Zampini PetscInt *constraints_n; 2312984c4197SStefano Zampini /* iterators */ 2313b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 2314984c4197SStefano Zampini /* BLAS integers */ 2315e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2316e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2317c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2318727cdba6SStefano Zampini /* reuse */ 23190e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 23200e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2321984c4197SStefano Zampini /* change of basis */ 2322b3d85658SStefano Zampini PetscBool qr_needed; 23239162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2324984c4197SStefano Zampini /* auxiliary stuff */ 232564efe560SStefano Zampini PetscInt *nnz,*is_indices; 23268a0068c3SStefano Zampini PetscInt ncc; 2327984c4197SStefano Zampini /* some quantities */ 232845a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2329a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2330984c4197SStefano Zampini 2331674ae819SStefano Zampini PetscFunctionBegin; 23328e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 23338e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 23348e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2335088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2336088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 23370e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 23380e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 23390e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 23400e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 23410e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2342088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2343cf5a6209SStefano Zampini 2344cf5a6209SStefano Zampini /* print some info */ 2345cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2346cf5a6209SStefano Zampini IS vertices; 2347cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2348cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2349cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2350cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2351cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2352cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2353cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2354fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2355fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2356cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2357cf5a6209SStefano Zampini } 2358cf5a6209SStefano Zampini 2359cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 23609162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2361cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2362cf5a6209SStefano Zampini const Vec *nearnullvecs; 2363cf5a6209SStefano Zampini Vec *localnearnullsp; 2364cf5a6209SStefano Zampini PetscScalar *array; 2365cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2366cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2367674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2368b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2369674ae819SStefano Zampini PetscScalar *work; 2370674ae819SStefano Zampini PetscReal *singular_vals; 2371674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2372674ae819SStefano Zampini PetscReal *rwork; 2373674ae819SStefano Zampini #endif 2374674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2375674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2376674ae819SStefano Zampini #else 2377964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2378964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2379674ae819SStefano Zampini #endif 2380674ae819SStefano Zampini 2381674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2382d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2383d06fc5fdSStefano Zampini /* free unneeded index sets */ 2384d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2385d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2386674ae819SStefano Zampini } 2387d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2388d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2389d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2390d06fc5fdSStefano Zampini } 2391d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2392d06fc5fdSStefano Zampini n_ISForEdges = 0; 2393d06fc5fdSStefano Zampini } 2394d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2395d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2396d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2397d06fc5fdSStefano Zampini } 2398d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2399d06fc5fdSStefano Zampini n_ISForFaces = 0; 2400d06fc5fdSStefano Zampini } 240170022509SStefano Zampini 240270022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 240370022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 240470022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 240570022509SStefano Zampini if (pcbddc->NullSpace) { 240670022509SStefano Zampini PetscBool tbool[2],gbool[2]; 240770022509SStefano Zampini 240870022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2409b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2410d06fc5fdSStefano Zampini if (!ISForEdges) { 2411d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2412d06fc5fdSStefano Zampini } 2413b8ffe317SStefano Zampini } 2414d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2415d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2416d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2417d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2418d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 241998a51de6SStefano Zampini } 242070022509SStefano Zampini #endif 242108122e43SStefano Zampini 2422674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2423674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2424674ae819SStefano Zampini if (nearnullsp) { 2425674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2426f4ddd8eeSStefano Zampini /* remove any stored info */ 2427f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2428f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2429f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2430f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2431f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2432473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2433f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2434f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2435f4ddd8eeSStefano Zampini } 2436984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2437984c4197SStefano Zampini nnsp_size = 0; 2438674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2439674ae819SStefano Zampini } 2440984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2441984c4197SStefano Zampini max_constraints = nnsp_size; 2442984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2443984c4197SStefano Zampini 2444674ae819SStefano Zampini /* 2445674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 24469162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 24479162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 24489162d606SStefano Zampini There can be multiple constraints per connected component 2449674ae819SStefano Zampini */ 2450674ae819SStefano Zampini n_vertices = 0; 2451674ae819SStefano Zampini if (ISForVertices) { 2452674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2453674ae819SStefano Zampini } 24549162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 24559162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 24569162d606SStefano Zampini 24579162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 24589162d606SStefano Zampini total_counts *= max_constraints; 2459674ae819SStefano Zampini total_counts += n_vertices; 24604641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 24619162d606SStefano Zampini 2462674ae819SStefano Zampini total_counts = 0; 2463674ae819SStefano Zampini max_size_of_constraint = 0; 2464674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 24659162d606SStefano Zampini IS used_is; 2466674ae819SStefano Zampini if (i<n_ISForEdges) { 24679162d606SStefano Zampini used_is = ISForEdges[i]; 2468674ae819SStefano Zampini } else { 24699162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2470674ae819SStefano Zampini } 24719162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2472674ae819SStefano Zampini total_counts += j; 2473674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2474674ae819SStefano Zampini } 24759162d606SStefano Zampini ierr = PetscMalloc3(total_counts*max_constraints+n_vertices,&constraints_data,total_counts+n_vertices,&constraints_idxs,total_counts+n_vertices,&constraints_idxs_B);CHKERRQ(ierr); 24769162d606SStefano Zampini 2477984c4197SStefano Zampini /* get local part of global near null space vectors */ 2478785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2479984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2480984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2481e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2482e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2483984c4197SStefano Zampini } 2484674ae819SStefano Zampini 2485242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2486242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2487a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2488242a89d7SStefano Zampini 2489984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2490a773dcb8SStefano Zampini if (!skip_lapack) { 2491674ae819SStefano Zampini PetscScalar temp_work; 2492911cabfeSStefano Zampini 2493674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2494984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2495785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2496785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2497785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2498674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2499785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2500674ae819SStefano Zampini #endif 2501674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2502c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2503c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2504674ae819SStefano Zampini lwork = -1; 2505674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2506674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2507c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2508674ae819SStefano Zampini #else 2509c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2510674ae819SStefano Zampini #endif 2511674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2512984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2513674ae819SStefano Zampini #else /* on missing GESVD */ 2514674ae819SStefano Zampini /* SVD */ 2515674ae819SStefano Zampini PetscInt max_n,min_n; 2516674ae819SStefano Zampini max_n = max_size_of_constraint; 2517984c4197SStefano Zampini min_n = max_constraints; 2518984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2519674ae819SStefano Zampini min_n = max_size_of_constraint; 2520984c4197SStefano Zampini max_n = max_constraints; 2521674ae819SStefano Zampini } 2522785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2523674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2524785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2525674ae819SStefano Zampini #endif 2526674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2527674ae819SStefano Zampini lwork = -1; 2528e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2529e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2530b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2531674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2532674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 25339162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr)); 2534674ae819SStefano Zampini #else 25359162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr)); 2536674ae819SStefano Zampini #endif 2537674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2538984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2539984c4197SStefano Zampini #endif /* on missing GESVD */ 2540674ae819SStefano Zampini /* Allocate optimal workspace */ 2541674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2542854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2543674ae819SStefano Zampini } 2544674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2545674ae819SStefano Zampini total_counts = 0; 25469162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 25479162d606SStefano Zampini constraints_data_ptr[0] = 0; 2548674ae819SStefano Zampini /* vertices */ 25499162d606SStefano Zampini if (n_vertices) { 2550674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 25519162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2552674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 25539162d606SStefano Zampini constraints_n[total_counts] = 1; 25549162d606SStefano Zampini constraints_data[total_counts] = 1.0; 25559162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 25569162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2557674ae819SStefano Zampini total_counts++; 2558674ae819SStefano Zampini } 2559674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2560674ae819SStefano Zampini n_vertices = total_counts; 2561674ae819SStefano Zampini } 2562984c4197SStefano Zampini 2563674ae819SStefano Zampini /* edges and faces */ 25649162d606SStefano Zampini total_counts_cc = total_counts; 2565911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 25669162d606SStefano Zampini IS used_is; 25679162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 25689162d606SStefano Zampini 2569911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 25709162d606SStefano Zampini used_is = ISForEdges[ncc]; 2571984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2572674ae819SStefano Zampini } else { 25739162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2574984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2575674ae819SStefano Zampini } 2576674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 25779162d606SStefano Zampini 25789162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 25799162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2580984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2581984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2582674ae819SStefano Zampini if (nnsp_has_cnst) { 25835b08dc53SStefano Zampini PetscScalar quad_value; 25849162d606SStefano Zampini 25859162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 25869162d606SStefano Zampini idxs_copied = PETSC_TRUE; 25879162d606SStefano Zampini 2588a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2589674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2590a773dcb8SStefano Zampini } else { 2591a773dcb8SStefano Zampini quad_value = 1.0; 2592a773dcb8SStefano Zampini } 2593674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 25949162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 2595674ae819SStefano Zampini } 25969162d606SStefano Zampini temp_constraints++; 2597674ae819SStefano Zampini total_counts++; 2598674ae819SStefano Zampini } 2599674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2600984c4197SStefano Zampini PetscReal real_value; 26019162d606SStefano Zampini PetscScalar *ptr_to_data; 26029162d606SStefano Zampini 2603984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 26049162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 2605674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 26069162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 2607674ae819SStefano Zampini } 2608984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2609984c4197SStefano Zampini /* check if array is null on the connected component */ 2610e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 26119162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 26125b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2613674ae819SStefano Zampini temp_constraints++; 2614674ae819SStefano Zampini total_counts++; 26159162d606SStefano Zampini if (!idxs_copied) { 26169162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 26179162d606SStefano Zampini idxs_copied = PETSC_TRUE; 2618674ae819SStefano Zampini } 2619674ae819SStefano Zampini } 26209162d606SStefano Zampini } 26219162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 262245a1bb75SStefano Zampini valid_constraints = temp_constraints; 2623eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2624a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 26259162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 26269162d606SStefano Zampini 26279162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2628a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 26299162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 2630a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 26319162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 2632a773dcb8SStefano Zampini } else { /* perform SVD */ 2633984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 26349162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2635674ae819SStefano Zampini 2636674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2637984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 2638984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 2639984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 2640984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 2641984c4197SStefano Zampini from that computed using LAPACKgesvd 2642984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 2643984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 2644984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 2645674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 2646e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2647984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2648674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 2649674ae819SStefano Zampini for (k=0;k<j+1;k++) { 26509162d606SStefano Zampini PetscStackCallBLAS("BLASdot",correlation_mat[j*temp_constraints+k] = BLASdot_(&Blas_N,ptr_to_data+k*size_of_constraint,&Blas_one,ptr_to_data+j*size_of_constraint,&Blas_one)); 2651674ae819SStefano Zampini } 2652674ae819SStefano Zampini } 2653e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 2654e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2655e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 2656674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2657c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 2658674ae819SStefano Zampini #else 2659c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 2660674ae819SStefano Zampini #endif 2661674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2662984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 2663984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 2664674ae819SStefano Zampini j = 0; 2665984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 2666674ae819SStefano Zampini total_counts = total_counts-j; 266745a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 2668e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 2669c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2670c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2671c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 2672c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2673c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 2674c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2675674ae819SStefano Zampini if (j<temp_constraints) { 2676984c4197SStefano Zampini PetscInt ii; 2677984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 2678674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 26799162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,ptr_to_data,&Blas_LDA,correlation_mat,&Blas_LDB,&zero,temp_basis,&Blas_LDC)); 2680674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2681984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 2682674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 26839162d606SStefano Zampini ptr_to_data[k*size_of_constraint+ii] = singular_vals[temp_constraints-1-k]*temp_basis[(temp_constraints-1-k)*size_of_constraint+ii]; 2684674ae819SStefano Zampini } 2685674ae819SStefano Zampini } 2686674ae819SStefano Zampini } 2687674ae819SStefano Zampini #else /* on missing GESVD */ 2688e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2689e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2690b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2691674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2692674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 26939162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr)); 2694674ae819SStefano Zampini #else 26959162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr)); 2696674ae819SStefano Zampini #endif 2697984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 2698674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2699984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 2700e310c8b4SStefano Zampini k = temp_constraints; 2701e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 2702674ae819SStefano Zampini j = 0; 2703e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 270445a1bb75SStefano Zampini valid_constraints = k-j; 2705911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 2706984c4197SStefano Zampini #endif /* on missing GESVD */ 2707674ae819SStefano Zampini } 2708a773dcb8SStefano Zampini } 27099162d606SStefano Zampini /* update pointers information */ 27109162d606SStefano Zampini if (valid_constraints) { 27119162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 27129162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 27139162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 27149162d606SStefano Zampini /* set change_of_basis flag */ 271545a1bb75SStefano Zampini if (boolforchange) { 2716b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 27179162d606SStefano Zampini } 2718b3d85658SStefano Zampini total_counts_cc++; 271945a1bb75SStefano Zampini } 272045a1bb75SStefano Zampini } 2721984c4197SStefano Zampini /* free workspace */ 27228f1c130eSStefano Zampini if (!skip_lapack) { 2723984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2724984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2725984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 2726984c4197SStefano Zampini #endif 2727984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 2728984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2729984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 2730984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 2731984c4197SStefano Zampini #endif 2732984c4197SStefano Zampini } 2733984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2734984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 2735984c4197SStefano Zampini } 2736984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 2737cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 2738cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2739cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2740cf5a6209SStefano Zampini } 2741cf5a6209SStefano Zampini if (n_ISForFaces) { 2742cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2743cf5a6209SStefano Zampini } 2744cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2745cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2746cf5a6209SStefano Zampini } 2747cf5a6209SStefano Zampini if (n_ISForEdges) { 2748cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2749cf5a6209SStefano Zampini } 2750cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 275108122e43SStefano Zampini } else { 275208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2753984c4197SStefano Zampini 275408122e43SStefano Zampini total_counts = 0; 275508122e43SStefano Zampini n_vertices = 0; 2756d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 2757d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 275808122e43SStefano Zampini } 275908122e43SStefano Zampini max_constraints = 0; 27609162d606SStefano Zampini total_counts_cc = 0; 276108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 276208122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 27639162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 276408122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 276508122e43SStefano Zampini } 27669162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 27679162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 27689162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 27699162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 277074d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 27719162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 27729162d606SStefano Zampini total_counts_cc = 0; 27739162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 27749162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 27759162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 277608122e43SStefano Zampini } 277708122e43SStefano Zampini } 27789162d606SStefano Zampini #if 0 27799162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 27809162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 27819162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 27829162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 27839162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 27849162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 27859162d606SStefano Zampini } 27869162d606SStefano Zampini printf("\n"); 27879162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 27889162d606SStefano Zampini } 27891b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 27908bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 27911b968477SStefano Zampini } 27921b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 27938bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] sub %d, edge %d, n %d\n",PetscGlobalRank,i,(PetscBool)PetscBTLookup(sub_schurs->is_edge,i),pcbddc->adaptive_constraints_n[i+n_vertices]); 27941b968477SStefano Zampini } 279508122e43SStefano Zampini #endif 279608122e43SStefano Zampini 27978bec7fa6SStefano Zampini max_size_of_constraint = 0; 27989162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) max_size_of_constraint = PetscMax(max_size_of_constraint,constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]); 27999162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 280008122e43SStefano Zampini /* Change of basis */ 2801b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 280208122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 280308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 280408122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 2805b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 280608122e43SStefano Zampini } 280708122e43SStefano Zampini } 280808122e43SStefano Zampini } 280908122e43SStefano Zampini } 2810984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 2811019a44ceSStefano Zampini /* allocating one extra space (in case an extra primal dof should be stored for the benign trick */ 2812019a44ceSStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+1,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 281308122e43SStefano Zampini 28149162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 28159162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 28169162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 28179162d606SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",constraints_idxs_ptr[total_counts_cc],i); 281808122e43SStefano Zampini } 2819674ae819SStefano Zampini 2820674ae819SStefano Zampini /* Create constraint matrix */ 2821674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 282216f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 2823984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 2824984c4197SStefano Zampini 2825984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 2826a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 2827a717540cSStefano Zampini qr_needed = PETSC_FALSE; 282874d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 2829984c4197SStefano Zampini total_primal_vertices=0; 2830b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 28319162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 28329162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 2833984c4197SStefano Zampini if (size_of_constraint == 1) { 28349162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 2835b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 283664efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 28379162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 28389162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 2839a717540cSStefano Zampini } 2840b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 284174d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 2842a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 2843a717540cSStefano Zampini qr_needed = PETSC_TRUE; 2844a717540cSStefano Zampini } 2845fa434743SStefano Zampini } else { 2846b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 2847fa434743SStefano Zampini } 2848a717540cSStefano Zampini } 2849b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 2850b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 2851674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 285270022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2853b3d85658SStefano Zampini 2854019a44ceSStefano Zampini /* allocating one extra space (in case an extra primal dof should be stored for the benign trick */ 2855019a44ceSStefano Zampini ierr = PetscMalloc2(pcbddc->local_primal_size_cc+1,&pcbddc->local_primal_ref_node,pcbddc->local_primal_size_cc+1,&pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 28560e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 28570e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 2858984c4197SStefano Zampini 2859984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 286074d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 2861785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2862984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 286374d5cdf7SStefano Zampini 2864984c4197SStefano Zampini j = total_primal_vertices; 286574d5cdf7SStefano Zampini total_counts = total_primal_vertices; 2866b3d85658SStefano Zampini cum = total_primal_vertices; 28679162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 28684641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2869b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 2870b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 2871b3d85658SStefano Zampini cum++; 28729162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 287374d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 287474d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 287574d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 287674d5cdf7SStefano Zampini } 28779162d606SStefano Zampini j += constraints_n[i]; 2878674ae819SStefano Zampini } 2879674ae819SStefano Zampini } 2880674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2881674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2882088faed8SStefano Zampini 2883674ae819SStefano Zampini /* set values in constraint matrix */ 2884984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 28850e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2886674ae819SStefano Zampini } 2887984c4197SStefano Zampini total_counts = total_primal_vertices; 28889162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 28894641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 28909162d606SStefano Zampini PetscInt *cols; 28919162d606SStefano Zampini 28929162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 28939162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 28949162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 28959162d606SStefano Zampini PetscInt row = total_counts+k; 28969162d606SStefano Zampini PetscScalar *vals; 28979162d606SStefano Zampini 28989162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 28999162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 29009162d606SStefano Zampini } 29019162d606SStefano Zampini total_counts += constraints_n[i]; 2902674ae819SStefano Zampini } 2903674ae819SStefano Zampini } 2904674ae819SStefano Zampini /* assembling */ 2905674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2906674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2907088faed8SStefano Zampini 2908984c4197SStefano Zampini /* 290945a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2910984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2911984c4197SStefano Zampini */ 2912674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2913674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2914026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2915984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2916984c4197SStefano Zampini /* working stuff for GEQRF */ 291781d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2918984c4197SStefano Zampini PetscBLASInt lqr_work; 2919984c4197SStefano Zampini /* working stuff for UNGQR */ 2920984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2921984c4197SStefano Zampini PetscBLASInt lgqr_work; 2922984c4197SStefano Zampini /* working stuff for TRTRS */ 2923984c4197SStefano Zampini PetscScalar *trs_rhs; 29243f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2925984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2926984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2927984c4197SStefano Zampini PetscScalar *start_vals; 2928984c4197SStefano Zampini /* working stuff for values insertion */ 29294641a718SStefano Zampini PetscBT is_primal; 293064efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 2931906d46d4SStefano Zampini /* matrix sizes */ 2932906d46d4SStefano Zampini PetscInt global_size,local_size; 2933906d46d4SStefano Zampini /* temporary change of basis */ 2934906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2935cf5a6209SStefano Zampini /* extra space for debugging */ 2936cf5a6209SStefano Zampini PetscScalar *dbg_work; 2937984c4197SStefano Zampini 2938906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2939906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 294016f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2941bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 2942906d46d4SStefano Zampini /* nonzeros for local mat */ 2943bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 2944bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 29459162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 2946a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 29479162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 2948a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 29499162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 2950a717540cSStefano Zampini } else { 29519162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 29529162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 2953a717540cSStefano Zampini } 2954a717540cSStefano Zampini } 2955a717540cSStefano Zampini } 2956906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2957bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2958a717540cSStefano Zampini /* Set initial identity in the matrix */ 2959bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 2960906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 2961a717540cSStefano Zampini } 2962a717540cSStefano Zampini 2963a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2964a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2965a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2966a717540cSStefano Zampini } 2967a717540cSStefano Zampini 2968a717540cSStefano Zampini 2969a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 2970a717540cSStefano Zampini /* 2971a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 2972a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 2973a717540cSStefano Zampini 2974a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 2975a717540cSStefano Zampini 2976a6b551f4SStefano 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) 2977a6b551f4SStefano Zampini 2978a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 2979a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 2980a717540cSStefano Zampini | ... | 2981a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 2982a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 2983a717540cSStefano Zampini 2984a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 2985a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 2986a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 2987a6b551f4SStefano Zampini 2988a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 2989a717540cSStefano Zampini */ 2990a717540cSStefano Zampini if (qr_needed) { 2991984c4197SStefano Zampini /* space to store Q */ 2992854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 2993984c4197SStefano Zampini /* first we issue queries for optimal work */ 29943f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 29953f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 29963f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2997984c4197SStefano Zampini lqr_work = -1; 29983f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 2999984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3000984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3001785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3002984c4197SStefano Zampini lgqr_work = -1; 30033f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 30043f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 30053f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 30063f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 30073f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 30083f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3009984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3010984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3011785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3012984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3013785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3014984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3015785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3016a717540cSStefano Zampini /* allocating workspace for check */ 3017a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3018cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3019a717540cSStefano Zampini } 3020a717540cSStefano Zampini } 3021984c4197SStefano Zampini /* array to store whether a node is primal or not */ 30224641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3023473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 30240e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 302539e2fb2aSStefano Zampini if (i != total_primal_vertices) { 302639e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 30274641a718SStefano Zampini } 302839e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 302939e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 303039e2fb2aSStefano Zampini } 303139e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3032984c4197SStefano Zampini 3033a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 30349162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 30359162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 30364641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3037984c4197SStefano Zampini /* get constraint info */ 30389162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3039984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3040984c4197SStefano Zampini 3041984c4197SStefano Zampini if (pcbddc->dbg_flag) { 30429162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraints %d: %d need a change of basis (size %d)\n",total_counts,primal_dofs,size_of_constraint);CHKERRQ(ierr); 3043674ae819SStefano Zampini } 3044984c4197SStefano Zampini 3045fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3046a717540cSStefano Zampini 3047a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3048a717540cSStefano Zampini if (pcbddc->dbg_flag) { 30499162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3050a717540cSStefano Zampini } 3051984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 30529162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3053984c4197SStefano Zampini 3054984c4197SStefano Zampini /* compute QR decomposition of constraints */ 30553f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 30563f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 30573f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3058674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30593f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3060984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3061674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3062984c4197SStefano Zampini 3063984c4197SStefano Zampini /* explictly compute R^-T */ 3064984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3065984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 30663f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 30673f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 30683f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 30693f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3070984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30713f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3072984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3073984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3074984c4197SStefano Zampini 3075a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 30763f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 30773f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 30783f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 30793f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3080984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30813f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3082984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3083984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3084984c4197SStefano Zampini 3085984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3086984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3087984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 30883f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 30893f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 30903f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 30913f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 30923f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 30933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3094984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30959162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&zero,constraints_data+constraints_data_ptr[total_counts],&Blas_LDC)); 3096984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 30979162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3098984c4197SStefano Zampini 3099984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 31009162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3101984c4197SStefano Zampini /* insert cols for primal dofs */ 3102984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3103984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 31049162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3105906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3106984c4197SStefano Zampini } 3107984c4197SStefano Zampini /* insert cols for dual dofs */ 3108984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 31099162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3110984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 31119162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3112906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3113984c4197SStefano Zampini j++; 3114674ae819SStefano Zampini } 3115674ae819SStefano Zampini } 3116984c4197SStefano Zampini 3117984c4197SStefano Zampini /* check change of basis */ 3118984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3119984c4197SStefano Zampini PetscInt ii,jj; 3120984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3121c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3122c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3123c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3124c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3125c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3126c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3127984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3128cf5a6209SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&Blas_M,&Blas_N,&Blas_K,&one,dbg_work,&Blas_LDA,qr_basis,&Blas_LDB,&zero,&dbg_work[size_of_constraint*primal_dofs],&Blas_LDC)); 3129984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3130984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3131984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3132cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3133cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 3134674ae819SStefano Zampini } 3135674ae819SStefano Zampini } 3136984c4197SStefano Zampini if (!valid_qr) { 313722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3138984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3139984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3140cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3141cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 3142674ae819SStefano Zampini } 3143cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3144cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 3145984c4197SStefano Zampini } 3146984c4197SStefano Zampini } 3147984c4197SStefano Zampini } 3148674ae819SStefano Zampini } else { 314922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3150674ae819SStefano Zampini } 3151674ae819SStefano Zampini } 3152a717540cSStefano Zampini } else { /* simple transformation block */ 3153a717540cSStefano Zampini PetscInt row,col; 3154a6b551f4SStefano Zampini PetscScalar val,norm; 3155a6b551f4SStefano Zampini 3156a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 31579162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,constraints_data+constraints_data_ptr[total_counts],&Blas_one,constraints_data+constraints_data_ptr[total_counts],&Blas_one)); 3158a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 31599162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 31609162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3161bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 31629162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3163906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 31649162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3165a717540cSStefano Zampini } else { 3166a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 31679162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3168a717540cSStefano Zampini if (row != col) { 31699162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3170a717540cSStefano Zampini } else { 31719162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3172a717540cSStefano Zampini } 3173906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3174a717540cSStefano Zampini } 3175a717540cSStefano Zampini } 3176a717540cSStefano Zampini } 317798a51de6SStefano Zampini if (pcbddc->dbg_flag) { 317822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3179a717540cSStefano Zampini } 3180674ae819SStefano Zampini } 3181984c4197SStefano Zampini } else { 3182984c4197SStefano Zampini if (pcbddc->dbg_flag) { 31839162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraint %d does not need a change of basis (size %d)\n",total_counts,size_of_constraint);CHKERRQ(ierr); 3184674ae819SStefano Zampini } 3185674ae819SStefano Zampini } 3186674ae819SStefano Zampini } 3187a717540cSStefano Zampini 3188a717540cSStefano Zampini /* free workspace */ 3189a717540cSStefano Zampini if (qr_needed) { 3190984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3191cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3192984c4197SStefano Zampini } 3193984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3194984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3195984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3196984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3197984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3198674ae819SStefano Zampini } 3199a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3200906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3201906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3202906d46d4SStefano Zampini 3203906d46d4SStefano Zampini /* assembling of global change of variable */ 3204bbb9e6c6SStefano Zampini { 3205bbb9e6c6SStefano Zampini Mat tmat; 320616f15bc4SStefano Zampini PetscInt bs; 320716f15bc4SStefano Zampini 3208906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3209906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3210bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3211bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3212bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3213bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 321416f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 321516f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3216906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3217bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3218bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3219bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3220bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3221bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3222e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3223e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3224bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3225bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3226906d46d4SStefano Zampini } 3227906d46d4SStefano Zampini /* check */ 3228906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3229906d46d4SStefano Zampini PetscReal error; 3230906d46d4SStefano Zampini Vec x,x_change; 3231906d46d4SStefano Zampini 3232906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3233906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3234906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3235906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3236e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3237e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3238bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 3239e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3240e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3241906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 3242906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3243906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3244906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3245bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 3246906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3247906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3248906d46d4SStefano Zampini } 3249b96c3477SStefano Zampini 3250b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 3251b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3252b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 3253b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 3254ac632422SStefano Zampini Mat S_new,tmat; 3255b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 3256b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 3257b087196eSStefano Zampini const PetscScalar *array; 3258b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 3259b087196eSStefano Zampini PetscInt i,n_V; 3260bbb9e6c6SStefano Zampini 3261bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 32626816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 3263b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 3264b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 3265b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 3266b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 3267bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 3268b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 3269ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3270b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 3271ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3272b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3273b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 3274b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3275b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3276b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 3277b087196eSStefano Zampini for (i=0;i<n_V;i++) { 3278b087196eSStefano Zampini PetscScalar val; 3279b087196eSStefano Zampini PetscInt idx; 3280b087196eSStefano Zampini 3281b087196eSStefano Zampini idx = idxs_V[i]; 3282b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 3283b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 3284b087196eSStefano Zampini } 3285b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3286b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3287ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 3288ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3289ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 3290ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3291b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 3292ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3293b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3294ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 3295ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3296ac632422SStefano Zampini } 3297b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 3298b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3299b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3300b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3301b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 3302b96c3477SStefano Zampini } 3303b96c3477SStefano Zampini } 3304906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 3305906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 3306b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3307b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 3308b9b85e73SStefano Zampini } 3309906d46d4SStefano Zampini 3310906d46d4SStefano Zampini /* set up change of basis context */ 3311906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 3312906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 3313906d46d4SStefano Zampini 3314906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 3315906d46d4SStefano Zampini PetscInt global_size,local_size; 3316906d46d4SStefano Zampini 3317906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3318906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3319906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 3320906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3321906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 3322906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 3323906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3324906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3325906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3326906d46d4SStefano Zampini } else { 3327906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3328906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3329906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3330906d46d4SStefano Zampini } 3331906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3332906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3333906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3334906d46d4SStefano Zampini } else { 3335906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3336906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3337906d46d4SStefano Zampini } 3338906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3339906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3340906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3341906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3342b9b85e73SStefano Zampini } 3343a717540cSStefano Zampini 3344019a44ceSStefano Zampini /* add pressure dof to set of primal nodes for numbering purposes */ 3345c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 3346c9ed8603SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx; 3347d16cbb6bSStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx; 3348019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 3349019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 3350019a44ceSStefano Zampini pcbddc->local_primal_size++; 3351019a44ceSStefano Zampini } 3352019a44ceSStefano Zampini 3353019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 3354727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3355727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 3356aff50787SStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc*sizeof(PetscScalar),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3357c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 33580e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 3359aff50787SStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscScalar),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3360727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3361727cdba6SStefano Zampini } 33620e6343abSStefano Zampini } 33630e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3364727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3365727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3366727cdba6SStefano Zampini 3367a717540cSStefano Zampini /* flush dbg viewer */ 3368b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3369b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3370b8ffe317SStefano Zampini } 3371a717540cSStefano Zampini 3372e310c8b4SStefano Zampini /* free workspace */ 3373a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 33744641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 337508122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 33769162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 33779162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 337808122e43SStefano Zampini } else { 33799162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 33809162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 33819162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 338208122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 338308122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 33849162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 33859162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 338608122e43SStefano Zampini } 3387674ae819SStefano Zampini PetscFunctionReturn(0); 3388674ae819SStefano Zampini } 3389674ae819SStefano Zampini 3390674ae819SStefano Zampini #undef __FUNCT__ 3391674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3392674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3393674ae819SStefano Zampini { 3394674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3395674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3396674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 33977fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3398674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3399674ae819SStefano Zampini 3400674ae819SStefano Zampini PetscFunctionBegin; 34018e61c736SStefano Zampini /* Reset previously computed graph */ 34028e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3403674ae819SStefano Zampini /* Init local Graph struct */ 34047fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 34053bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3406674ae819SStefano Zampini 3407575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 3408575ad6abSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 3409575ad6abSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 3410575ad6abSStefano Zampini } 34119577ea80SStefano Zampini 3412674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 34134d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 34144d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 34154d379d7bSStefano Zampini PetscInt nvtxs; 3416e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3417674ae819SStefano Zampini 34184d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 34192fffb893SStefano Zampini 34202fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34212fffb893SStefano Zampini if (flg_row) { 34224d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3423b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 34242fffb893SStefano Zampini } 34252fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34269b28b941SStefano Zampini } else if (pcbddc->current_level && pcis->n_B) { /* just compute subdomain's connected components for coarser levels when the local boundary is not empty */ 34274d379d7bSStefano Zampini IS is_dummy; 34284d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 34294d379d7bSStefano Zampini PetscInt j,sum; 34304d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 34314d379d7bSStefano Zampini const PetscInt *idxs; 34324d379d7bSStefano Zampini PCBDDCGraph graph; 34334d379d7bSStefano Zampini PetscBT is_on_boundary; 34344d379d7bSStefano Zampini 34354d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 34364d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 34374d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 34384d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 34397fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 34404d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3441e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3442e496cd5dSStefano Zampini if (flg_row) { 34434d379d7bSStefano Zampini graph->xadj = xadj; 34444d379d7bSStefano Zampini graph->adjncy = adjncy; 3445e496cd5dSStefano Zampini } 34464d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 34474d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3448e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34494d379d7bSStefano Zampini 34504d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 34519b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 34524d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 34534d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 34544d379d7bSStefano Zampini } 34554d379d7bSStefano Zampini } 34564d379d7bSStefano Zampini 3457e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 34584d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 34594d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 34604d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 34614d379d7bSStefano Zampini } 34624d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 34634d379d7bSStefano Zampini 3464e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 34654d379d7bSStefano Zampini sum = 0; 34664d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 34674d379d7bSStefano Zampini PetscInt sizecc = 0; 34684d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 34694d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 34704d379d7bSStefano Zampini sizecc++; 34714d379d7bSStefano Zampini } 34724d379d7bSStefano Zampini } 34734d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 34744d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 34754d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 34764d379d7bSStefano Zampini } 34774d379d7bSStefano Zampini } 34784d379d7bSStefano Zampini sum += sizecc*sizecc; 34794d379d7bSStefano Zampini } 34804d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 34814d379d7bSStefano Zampini sum = 0; 3482e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 34834d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 34844d379d7bSStefano Zampini cxadj[i] = sum; 34854d379d7bSStefano Zampini sum += temp; 34864d379d7bSStefano Zampini } 3487e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 34884d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 34894d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 34904d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 34914d379d7bSStefano Zampini PetscInt k,sizecc = 0; 34924d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 34934d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 34944d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 34954d379d7bSStefano Zampini sizecc++; 34964d379d7bSStefano Zampini } 34974d379d7bSStefano Zampini } 34984d379d7bSStefano Zampini } 34994d379d7bSStefano Zampini } 35004d379d7bSStefano Zampini } 35019b28b941SStefano Zampini if (sum) { 3502e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 35034d379d7bSStefano Zampini } else { 35044d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 35054d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 35064d379d7bSStefano Zampini } 35074d379d7bSStefano Zampini graph->xadj = 0; 35084d379d7bSStefano Zampini graph->adjncy = 0; 35094d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 35104d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 35114d379d7bSStefano Zampini } 3512674ae819SStefano Zampini } 35139b28b941SStefano Zampini if (pcbddc->dbg_flag) { 35149b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3515674ae819SStefano Zampini } 3516674ae819SStefano Zampini 351763602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3518674ae819SStefano Zampini vertex_size = 1; 351963602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 352063602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 352195ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 352263602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3523e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 352463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3525674ae819SStefano Zampini } 352663602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 352763602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 352863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3529674ae819SStefano Zampini } 353063602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3531674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 353263602bcaSStefano Zampini } else { 353363602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 353463602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3535854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 353663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 353763602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 353863602bcaSStefano Zampini } 353963602bcaSStefano Zampini } 3540674ae819SStefano Zampini } 3541674ae819SStefano Zampini 3542674ae819SStefano Zampini /* Setup of Graph */ 3543785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3544e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3545785d1243SStefano Zampini } 3546785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3547e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3548785d1243SStefano Zampini } 3549302440fdSBarry Smith ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices);CHKERRQ(ierr); 3550674ae819SStefano Zampini 3551674ae819SStefano Zampini /* Graph's connected components analysis */ 3552674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3553674ae819SStefano Zampini 3554674ae819SStefano Zampini /* print some info to stdout */ 3555674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3556302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3557674ae819SStefano Zampini } 3558fb180af4SStefano Zampini 3559fb180af4SStefano Zampini /* mark topography has done */ 3560fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3561674ae819SStefano Zampini PetscFunctionReturn(0); 3562674ae819SStefano Zampini } 3563674ae819SStefano Zampini 3564dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3565674ae819SStefano Zampini #undef __FUNCT__ 3566674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3567dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3568674ae819SStefano Zampini { 3569dc456d91SStefano Zampini PetscSF sf; 3570dc456d91SStefano Zampini PetscLayout map; 3571dc456d91SStefano Zampini const PetscInt *idxs; 3572dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 3573dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 3574dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 3575dc456d91SStefano Zampini PetscMPIInt commsize; 3576674ae819SStefano Zampini PetscBool first_found; 3577674ae819SStefano Zampini PetscErrorCode ierr; 3578674ae819SStefano Zampini 3579674ae819SStefano Zampini PetscFunctionBegin; 3580dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 3581dc456d91SStefano Zampini if (subset_mult) { 3582dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 3583dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 3584dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 3585674ae819SStefano Zampini } 3586dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 3587dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 3588dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 3589dc456d91SStefano Zampini for (i=0;i<n;i++) { 3590dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 3591dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 3592674ae819SStefano Zampini } 3593dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 3594dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3595dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 3596dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 3597dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 3598dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 3599dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 3600dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 3601dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 3602dc456d91SStefano Zampini 3603dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 3604dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 3605dc456d91SStefano Zampini if (subset_mult) { 3606dc456d91SStefano Zampini const PetscInt* idxs_mult; 3607dc456d91SStefano Zampini 3608dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3609dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 3610dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3611674ae819SStefano Zampini } else { 3612dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 3613674ae819SStefano Zampini } 3614dc456d91SStefano Zampini /* local size of new subset */ 3615dc456d91SStefano Zampini n_n = 0; 3616dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 3617dc456d91SStefano Zampini 3618dc456d91SStefano Zampini /* global indexes in layout */ 3619dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 3620dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 3621dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 3622dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 3623dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 3624dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 3625dc456d91SStefano Zampini 3626dc456d91SStefano Zampini /* reduce from leaves to roots */ 3627dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 362864a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 362964a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 3630dc456d91SStefano Zampini 3631dc456d91SStefano Zampini /* count indexes in local part of layout */ 3632674ae819SStefano Zampini nlocals = 0; 3633674ae819SStefano Zampini first_index = -1; 3634674ae819SStefano Zampini first_found = PETSC_FALSE; 3635dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 3636dc456d91SStefano Zampini if (!first_found && root_data[i]) { 3637674ae819SStefano Zampini first_found = PETSC_TRUE; 3638674ae819SStefano Zampini first_index = i; 3639674ae819SStefano Zampini } 3640dc456d91SStefano Zampini nlocals += root_data[i]; 3641674ae819SStefano Zampini } 3642dc456d91SStefano Zampini 3643dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 36445fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 3645dc456d91SStefano Zampini start = 0; 364664a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 36475fa240b1SStefano Zampini #else 364864a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 36495fa240b1SStefano Zampini start = start-nlocals; 36505fa240b1SStefano Zampini #endif 36515fa240b1SStefano Zampini 3652dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 3653dc456d91SStefano Zampini *N_n = start + nlocals; 3654dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 3655dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3656674ae819SStefano Zampini } 36575fa240b1SStefano Zampini 36585fa240b1SStefano Zampini /* adapt root data with cumulative */ 3659674ae819SStefano Zampini if (first_found) { 3660dc456d91SStefano Zampini PetscInt old_index; 3661dc456d91SStefano Zampini 3662dc456d91SStefano Zampini root_data[first_index] += start; 3663674ae819SStefano Zampini old_index = first_index; 3664dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 3665dc456d91SStefano Zampini if (root_data[i]) { 3666dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 3667674ae819SStefano Zampini old_index = i; 3668674ae819SStefano Zampini } 3669674ae819SStefano Zampini } 3670674ae819SStefano Zampini } 3671dc456d91SStefano Zampini 3672dc456d91SStefano Zampini /* from roots to leaves */ 3673dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3674dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3675dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 3676dc456d91SStefano Zampini 3677dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 3678dc456d91SStefano Zampini if (subset_mult) { 3679dc456d91SStefano Zampini const PetscInt* idxs_mult; 3680dc456d91SStefano Zampini PetscInt cum; 3681dc456d91SStefano Zampini 3682dc456d91SStefano Zampini cum = 0; 3683dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3684dc456d91SStefano Zampini for (i=0;i<n;i++) { 3685dc456d91SStefano Zampini PetscInt j; 3686dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 3687674ae819SStefano Zampini } 3688dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3689674ae819SStefano Zampini } else { 3690dc456d91SStefano Zampini for (i=0;i<n;i++) { 3691dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 3692674ae819SStefano Zampini } 3693674ae819SStefano Zampini } 3694dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 3695dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 3696674ae819SStefano Zampini PetscFunctionReturn(0); 3697674ae819SStefano Zampini } 36989a7d3425SStefano Zampini 36999a7d3425SStefano Zampini #undef __FUNCT__ 37009a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 37019a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 37029a7d3425SStefano Zampini { 37039a7d3425SStefano Zampini PetscInt i,j; 37049a7d3425SStefano Zampini PetscScalar *alphas; 37059a7d3425SStefano Zampini PetscErrorCode ierr; 37069a7d3425SStefano Zampini 37079a7d3425SStefano Zampini PetscFunctionBegin; 37089a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 3709785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 37109a7d3425SStefano Zampini for (i=0;i<n;i++) { 37119a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 37129a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 37139a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 37149a7d3425SStefano Zampini } 37159a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 37169a7d3425SStefano Zampini PetscFunctionReturn(0); 37179a7d3425SStefano Zampini } 37189a7d3425SStefano Zampini 3719e7931f94SStefano Zampini #undef __FUNCT__ 372070cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 3721b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 3722e7931f94SStefano Zampini { 372352e5ac9dSStefano Zampini IS ranks_send_to; 3724e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 3725e7931f94SStefano Zampini PetscMPIInt size,rank,color; 372652e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 372752e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 37283837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 37292b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 3730e7931f94SStefano Zampini PetscSubcomm subcomm; 373152e5ac9dSStefano Zampini PetscErrorCode ierr; 3732a57a6d2fSStefano Zampini 3733e7931f94SStefano Zampini PetscFunctionBegin; 37342b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 37352b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 37362b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 3737e7931f94SStefano Zampini 3738e7931f94SStefano Zampini /* Get info on mapping */ 37393bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 37403bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3741e7931f94SStefano Zampini 3742e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 3743785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 3744e7931f94SStefano Zampini xadj[0] = 0; 3745e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 3746785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 3747785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 3748e7931f94SStefano Zampini 37492b510759SStefano Zampini if (threshold) { 3750d023bfaeSStefano Zampini PetscInt xadj_count = 0; 37512b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 3752d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 3753d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 3754d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 3755d023bfaeSStefano Zampini xadj_count++; 3756e7931f94SStefano Zampini } 3757e7931f94SStefano Zampini } 3758d023bfaeSStefano Zampini xadj[1] = xadj_count; 3759c8587f34SStefano Zampini } else { 3760e7931f94SStefano Zampini if (xadj[1]) { 3761e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 3762e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 3763c8587f34SStefano Zampini } 3764e7931f94SStefano Zampini } 37653bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3766e7931f94SStefano Zampini if (use_square) { 3767e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3768e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3769e7931f94SStefano Zampini } 3770e7931f94SStefano Zampini } 3771e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3772e7931f94SStefano Zampini 37733837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3774e7931f94SStefano Zampini 3775e7931f94SStefano Zampini /* 3776e7931f94SStefano Zampini Restrict work on active processes only. 3777e7931f94SStefano Zampini */ 3778e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3779e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3780e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 37812b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3782d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3783e7931f94SStefano Zampini if (color) { 3784e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3785e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3786e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3787c8587f34SStefano Zampini } else { 378852e5ac9dSStefano Zampini Mat subdomain_adj; 378952e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 379052e5ac9dSStefano Zampini MatPartitioning partitioner; 379152e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 379252e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 3793b0c7d250SStefano Zampini PetscBool aggregate; 3794b0c7d250SStefano Zampini 3795306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 3796785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3797e7931f94SStefano Zampini prank = rank; 3798306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 37998002ef2cSStefano Zampini /* 3800e7931f94SStefano Zampini for (i=0;i<size;i++) { 3801e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3802c8587f34SStefano Zampini } 38038002ef2cSStefano Zampini */ 3804e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3805e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3806c8587f34SStefano Zampini } 3807e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3808b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 3809b0c7d250SStefano Zampini if (aggregate) { 3810b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 3811b0c7d250SStefano Zampini PetscMPIInt nrank; 3812b0c7d250SStefano Zampini PetscScalar *vals; 3813b0c7d250SStefano Zampini 3814b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 3815b0c7d250SStefano Zampini lrows = 0; 3816b0c7d250SStefano Zampini if (nrank<redprocs) { 3817b0c7d250SStefano Zampini lrows = size/redprocs; 3818b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 3819b0c7d250SStefano Zampini } 38205fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 3821b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 3822b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3823b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3824b0c7d250SStefano Zampini row = nrank; 3825b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 3826b0c7d250SStefano Zampini cols = adjncy; 3827b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 3828b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 3829b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 3830b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3831b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 383252e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 383352e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 383452e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3835b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 3836b0c7d250SStefano Zampini } else { 3837306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 3838b0c7d250SStefano Zampini } 383922b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3840e7931f94SStefano Zampini 3841e7931f94SStefano Zampini /* Partition */ 3842306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 3843e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3844e7931f94SStefano Zampini if (use_vwgt) { 38453837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3846e7931f94SStefano Zampini v_wgt[0] = local_size; 3847e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3848c8587f34SStefano Zampini } 384928143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 385028143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3851e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3852e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 385322b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3854e7931f94SStefano Zampini 385552e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 385652e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 385752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 385852e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3859b0c7d250SStefano Zampini if (!redprocs) { 3860b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 386128143c3dSStefano Zampini } else { 3862b0c7d250SStefano Zampini PetscInt idxs[1]; 3863b0c7d250SStefano Zampini PetscMPIInt tag; 3864b0c7d250SStefano Zampini MPI_Request *reqs; 3865b0c7d250SStefano Zampini 3866b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 3867b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 3868b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 3869b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 387028143c3dSStefano Zampini } 3871b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 3872b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3873b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 3874b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 3875e7931f94SStefano Zampini } 387652e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3877e7931f94SStefano Zampini /* clean up */ 3878e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 387952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 3880e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3881e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3882e7931f94SStefano Zampini } 3883e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3884e7931f94SStefano Zampini 3885e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3886e7931f94SStefano Zampini i = 1; 3887e7931f94SStefano Zampini if (color) i=0; 3888e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3889e7931f94SStefano Zampini /* get back IS */ 3890e7931f94SStefano Zampini *is_sends = ranks_send_to; 3891e7931f94SStefano Zampini PetscFunctionReturn(0); 3892e7931f94SStefano Zampini } 3893e7931f94SStefano Zampini 3894e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3895e7931f94SStefano Zampini 3896e7931f94SStefano Zampini #undef __FUNCT__ 3897e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 389853a05cb3SStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 3899e7931f94SStefano Zampini { 390070cf5478SStefano Zampini Mat local_mat; 3901e7931f94SStefano Zampini IS is_sends_internal; 39029d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 390328143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 39049d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3905e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3906e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3907e7931f94SStefano Zampini const PetscInt* is_indices; 3908e7931f94SStefano Zampini MatType new_local_type; 3909e7931f94SStefano Zampini /* buffers */ 3910e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 391128143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 39129d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3913e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3914e7931f94SStefano Zampini /* MPI */ 391528143c3dSStefano Zampini MPI_Comm comm,comm_n; 391628143c3dSStefano Zampini PetscSubcomm subcomm; 3917e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 391828143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 391928143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 392028143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 392128143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 392228143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3923e7931f94SStefano Zampini PetscErrorCode ierr; 3924e7931f94SStefano Zampini 3925e7931f94SStefano Zampini PetscFunctionBegin; 392628143c3dSStefano Zampini /* TODO: add missing checks */ 392728143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 392828143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 392928143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 393028143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3931e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 393228143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3933e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3934e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3935e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3936e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3937e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 393828143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 393970cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 394070cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 394128143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 394270cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 394370cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 394470cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 394570cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 394670cf5478SStefano Zampini } 3947e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 3948e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 3949e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 3950e7931f94SStefano Zampini if (!is_sends) { 395128143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 3952b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 3953c8587f34SStefano Zampini } else { 3954e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 3955e7931f94SStefano Zampini is_sends_internal = is_sends; 3956c8587f34SStefano Zampini } 3957e7931f94SStefano Zampini 3958e7931f94SStefano Zampini /* get comm */ 3959a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3960e7931f94SStefano Zampini 3961e7931f94SStefano Zampini /* compute number of sends */ 3962e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 3963e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 3964e7931f94SStefano Zampini 3965e7931f94SStefano Zampini /* compute number of receives */ 3966e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 3967785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 3968e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 3969e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3970e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 3971e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 3972e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 3973e7931f94SStefano Zampini 397428143c3dSStefano Zampini /* restrict comm if requested */ 397528143c3dSStefano Zampini subcomm = 0; 397628143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 397728143c3dSStefano Zampini if (restrict_comm) { 3978779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 3979779c1cceSStefano Zampini 398028143c3dSStefano Zampini color = 0; 398153a05cb3SStefano Zampini if (restrict_full) { 398253a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 398353a05cb3SStefano Zampini } else { 398453a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 398553a05cb3SStefano Zampini } 398628143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 398728143c3dSStefano Zampini subcommsize = commsize - subcommsize; 398828143c3dSStefano Zampini /* check if reuse has been requested */ 398928143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 399028143c3dSStefano Zampini if (*mat_n) { 399128143c3dSStefano Zampini PetscMPIInt subcommsize2; 399228143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 399328143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 399428143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 399528143c3dSStefano Zampini } else { 399628143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 399728143c3dSStefano Zampini } 399828143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 3999779c1cceSStefano Zampini PetscMPIInt rank; 4000779c1cceSStefano Zampini 4001779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 400228143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 400328143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 400428143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4005306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 400628143c3dSStefano Zampini } 400728143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 400828143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 400928143c3dSStefano Zampini } else { 401028143c3dSStefano Zampini comm_n = comm; 401128143c3dSStefano Zampini } 401228143c3dSStefano Zampini 4013e7931f94SStefano Zampini /* prepare send/receive buffers */ 4014785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4015e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4016785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4017e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 401828143c3dSStefano Zampini if (nis) { 4019854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 402028143c3dSStefano Zampini } 4021e7931f94SStefano Zampini 402228143c3dSStefano Zampini /* Get data from local matrices */ 4023e7931f94SStefano Zampini if (!isdense) { 4024a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4025e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4026e7931f94SStefano Zampini /* 4027e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4028e7931f94SStefano Zampini send_buffer_idxs should contain: 4029e7931f94SStefano Zampini - MatType_PRIVATE type 4030e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4031e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4032e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4033e7931f94SStefano Zampini */ 4034e7931f94SStefano Zampini } else { 4035e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 40363bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4037854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4038e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4039e7931f94SStefano Zampini send_buffer_idxs[1] = i; 40403bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4041e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 40423bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4043e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4044e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4045e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4046e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4047c8587f34SStefano Zampini } 4048c8587f34SStefano Zampini } 4049e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 405028143c3dSStefano Zampini /* additional is (if any) */ 405128143c3dSStefano Zampini if (nis) { 405228143c3dSStefano Zampini PetscMPIInt psum; 405328143c3dSStefano Zampini PetscInt j; 405428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 405528143c3dSStefano Zampini PetscInt plen; 405628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 405728143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 405828143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 405928143c3dSStefano Zampini } 4060854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 406128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 406228143c3dSStefano Zampini PetscInt plen; 406328143c3dSStefano Zampini const PetscInt *is_array_idxs; 406428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 406528143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 406628143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 406728143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 406828143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 406928143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 407028143c3dSStefano Zampini } 407128143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 407228143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 407328143c3dSStefano Zampini } 407428143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 407528143c3dSStefano Zampini } 407628143c3dSStefano Zampini 4077e7931f94SStefano Zampini buf_size_idxs = 0; 4078e7931f94SStefano Zampini buf_size_vals = 0; 407928143c3dSStefano Zampini buf_size_idxs_is = 0; 4080e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4081e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4082e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 408328143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4084e7931f94SStefano Zampini } 4085785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4086785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 408795ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4088e7931f94SStefano Zampini 4089e7931f94SStefano Zampini /* get new tags for clean communications */ 4090e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4091e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 409228143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4093e7931f94SStefano Zampini 4094e7931f94SStefano Zampini /* allocate for requests */ 4095785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4096785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 409795ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4098785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4099785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 410095ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4101e7931f94SStefano Zampini 4102e7931f94SStefano Zampini /* communications */ 4103e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4104e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 410528143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4106e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4107e7931f94SStefano Zampini source_dest = onodes[i]; 4108e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4109e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4110e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4111e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 411228143c3dSStefano Zampini if (nis) { 411328143c3dSStefano 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); 411428143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 411528143c3dSStefano Zampini } 4116e7931f94SStefano Zampini } 4117e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4118e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4119e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4120e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 412128143c3dSStefano Zampini if (nis) { 412228143c3dSStefano 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); 412328143c3dSStefano Zampini } 4124e7931f94SStefano Zampini } 4125e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4126e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4127e7931f94SStefano Zampini 4128e7931f94SStefano Zampini /* assemble new l2g map */ 4129e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4130e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 41319d30be91SStefano Zampini new_local_rows = 0; 4132e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 41339d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4134e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4135e7931f94SStefano Zampini } 41369d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4137e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 41389d30be91SStefano Zampini new_local_rows = 0; 4139e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 41409d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 41419d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4142e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4143e7931f94SStefano Zampini } 41449d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 41459d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4146e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4147e7931f94SStefano Zampini 4148e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4149e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4150e7931f94SStefano 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) */ 4151e7931f94SStefano Zampini if (n_recvs) { 415228143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4153e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4154e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4155e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4156e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4157e7931f94SStefano Zampini break; 4158e7931f94SStefano Zampini } 4159e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4160e7931f94SStefano Zampini } 4161e7931f94SStefano Zampini switch (new_local_type_private) { 416228143c3dSStefano Zampini case MATDENSE_PRIVATE: 416328143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4164e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4165e7931f94SStefano Zampini bs = 1; 416628143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 416728143c3dSStefano Zampini new_local_type = MATSEQDENSE; 416828143c3dSStefano Zampini bs = 1; 416928143c3dSStefano Zampini } 4170e7931f94SStefano Zampini break; 4171e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4172e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4173e7931f94SStefano Zampini bs = 1; 4174e7931f94SStefano Zampini break; 4175e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4176e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4177e7931f94SStefano Zampini break; 4178e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4179e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4180e7931f94SStefano Zampini break; 4181e7931f94SStefano Zampini default: 41829d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4183e7931f94SStefano Zampini break; 4184e7931f94SStefano Zampini } 418528143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 418628143c3dSStefano Zampini new_local_type = MATSEQDENSE; 418728143c3dSStefano Zampini bs = 1; 4188e7931f94SStefano Zampini } 4189e7931f94SStefano Zampini 419070cf5478SStefano Zampini /* create MATIS object if needed */ 419170cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4192e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4193e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 419470cf5478SStefano Zampini } else { 419570cf5478SStefano Zampini /* it also destroys the local matrices */ 419670cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 419770cf5478SStefano Zampini } 419870cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4199e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 42009d30be91SStefano Zampini 42019d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 42029d30be91SStefano Zampini 42039d30be91SStefano Zampini /* Global to local map of received indices */ 42049d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 42059d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 42069d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 42079d30be91SStefano Zampini 42089d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 42099d30be91SStefano Zampini buf_size_idxs = 0; 42109d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 42119d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 42129d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 42139d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 42149d30be91SStefano Zampini } 42159d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 42169d30be91SStefano Zampini 42179d30be91SStefano Zampini /* set preallocation */ 42189d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 42199d30be91SStefano Zampini if (!newisdense) { 42209d30be91SStefano Zampini PetscInt *new_local_nnz=0; 42219d30be91SStefano Zampini 42229d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 42239d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 42249d30be91SStefano Zampini if (n_recvs) { 42259d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 42269d30be91SStefano Zampini } 42279d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 42289d30be91SStefano Zampini PetscInt j; 42299d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 42309d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 42319d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 42329d30be91SStefano Zampini } 42339d30be91SStefano Zampini } else { 42349d30be91SStefano Zampini /* TODO */ 42359d30be91SStefano Zampini } 42369d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 42379d30be91SStefano Zampini } 42389d30be91SStefano Zampini if (new_local_nnz) { 42399d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 42409d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 42419d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 42429d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 42439d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 42449d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 42459d30be91SStefano Zampini } else { 42469d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 42479d30be91SStefano Zampini } 42489d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 42499d30be91SStefano Zampini } else { 42509d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 42519d30be91SStefano Zampini } 4252e7931f94SStefano Zampini 4253e7931f94SStefano Zampini /* set values */ 4254e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 42559d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 4256e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4257e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 4258e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 42599d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 4260e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4261e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4262e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 426328143c3dSStefano Zampini } else { 426428143c3dSStefano Zampini /* TODO */ 4265e7931f94SStefano Zampini } 4266e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4267e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 4268e7931f94SStefano Zampini } 4269e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4270e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 427170cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 427270cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 42739d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 42749d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 4275e7931f94SStefano Zampini 4276dfd14d43SStefano Zampini #if 0 427728143c3dSStefano Zampini if (!restrict_comm) { /* check */ 4278e7931f94SStefano Zampini Vec lvec,rvec; 4279e7931f94SStefano Zampini PetscReal infty_error; 4280e7931f94SStefano Zampini 42812a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 4282e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 4283e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 4284e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 428570cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 4286e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4287e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 4288e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 4289e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 4290e7931f94SStefano Zampini } 429128143c3dSStefano Zampini #endif 4292e7931f94SStefano Zampini 429328143c3dSStefano Zampini /* assemble new additional is (if any) */ 429428143c3dSStefano Zampini if (nis) { 429528143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 429628143c3dSStefano Zampini 429728143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4298854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 429928143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 430028143c3dSStefano Zampini psum = 0; 430128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 430228143c3dSStefano Zampini for (j=0;j<nis;j++) { 430328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 430428143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 430528143c3dSStefano Zampini psum += plen; 430628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 430728143c3dSStefano Zampini } 430828143c3dSStefano Zampini } 4309854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 4310854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 431128143c3dSStefano Zampini for (i=1;i<nis;i++) { 431228143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 431328143c3dSStefano Zampini } 431428143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 431528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 431628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 431728143c3dSStefano Zampini for (j=0;j<nis;j++) { 431828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 431928143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 432028143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 432128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 432228143c3dSStefano Zampini } 432328143c3dSStefano Zampini } 432428143c3dSStefano Zampini for (i=0;i<nis;i++) { 432528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 432628143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 432728143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 432828143c3dSStefano Zampini } 432928143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 433028143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 433128143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 433228143c3dSStefano Zampini } 4333e7931f94SStefano Zampini /* free workspace */ 433428143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4335e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4336e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4337e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4338e7931f94SStefano Zampini if (isdense) { 4339e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4340e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4341e7931f94SStefano Zampini } else { 4342e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4343e7931f94SStefano Zampini } 434428143c3dSStefano Zampini if (nis) { 434528143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 434628143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 434728143c3dSStefano Zampini } 4348e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4349e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 435028143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4351e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4352e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 435328143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4354e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4355e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4356e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4357e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4358e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 435928143c3dSStefano Zampini if (nis) { 436028143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 436128143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 436228143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 436328143c3dSStefano Zampini } 436428143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 436528143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 436628143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 436728143c3dSStefano Zampini for (i=0;i<nis;i++) { 436828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 436928143c3dSStefano Zampini } 437053a05cb3SStefano Zampini *mat_n = NULL; 437128143c3dSStefano Zampini } 4372e7931f94SStefano Zampini PetscFunctionReturn(0); 4373e7931f94SStefano Zampini } 4374a57a6d2fSStefano Zampini 437512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4376af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 437712edc857SStefano Zampini 4378c8587f34SStefano Zampini #undef __FUNCT__ 4379c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4380c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4381c8587f34SStefano Zampini { 4382c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4383c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 438420a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 43859881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 438620a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 43876e683305SStefano Zampini IS coarse_is,*isarray; 43886e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 43896e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 4390f9eb5b7dSStefano Zampini PC pc_temp; 4391c8587f34SStefano Zampini PCType coarse_pc_type; 4392c8587f34SStefano Zampini KSPType coarse_ksp_type; 4393f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 43944f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 43956e683305SStefano Zampini Mat t_coarse_mat_is; 43966e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 43976e683305SStefano Zampini PetscMPIInt all_procs; 439874e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 439968457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 440022bc73bbSStefano Zampini PetscScalar *array; 44019881197aSStefano Zampini PetscErrorCode ierr; 4402fdc09c96SStefano Zampini 4403c8587f34SStefano Zampini PetscFunctionBegin; 4404c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 440568457ee5SStefano 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 */ 4406fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 44075a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4408fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4409f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4410f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4411f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4412fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 441351bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 441451bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4415dc4bcba2SStefano Zampini PC pc; 4416dc4bcba2SStefano Zampini PetscBool isbddc; 4417dc4bcba2SStefano Zampini 4418dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4419dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4420dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4421dc4bcba2SStefano Zampini if (isbddc) { 4422dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4423dc4bcba2SStefano Zampini } 4424727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4425fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4426fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4427fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4428f4ddd8eeSStefano Zampini } 4429fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4430fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4431f4ddd8eeSStefano Zampini } 443270cf5478SStefano Zampini /* reset any subassembling information */ 443370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 44346e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 44356e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4436fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4437f4ddd8eeSStefano Zampini } 4438c8587f34SStefano Zampini 44396e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 44402b510759SStefano Zampini im_active = !!(pcis->n); 44412b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 44426e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 44436e683305SStefano Zampini void_procs = all_procs-active_procs; 44446e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 444574e2c79eSStefano Zampini redist = PETSC_FALSE; 444622bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 44476e683305SStefano Zampini csin_ml = PETSC_TRUE; 44486e683305SStefano Zampini ncoarse_ml = void_procs; 4449779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4450779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 44516e683305SStefano Zampini csin_ds = PETSC_TRUE; 445218a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 445318a45a71SStefano Zampini redist = PETSC_TRUE; 445418a45a71SStefano Zampini } else { 44556e683305SStefano Zampini csin_ds = PETSC_TRUE; 4456779c1cceSStefano Zampini ncoarse_ds = active_procs; 4457779c1cceSStefano Zampini redist = PETSC_TRUE; 445818a45a71SStefano Zampini } 44596e683305SStefano Zampini } else { 44606e683305SStefano Zampini csin_ml = PETSC_FALSE; 44616e683305SStefano Zampini ncoarse_ml = all_procs; 44626e683305SStefano Zampini if (void_procs) { 44636e683305SStefano Zampini csin_ds = PETSC_TRUE; 44646e683305SStefano Zampini ncoarse_ds = void_procs; 44656e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 44666e683305SStefano Zampini } else { 4467779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 446874e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 446974e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 447074e2c79eSStefano Zampini redist = PETSC_TRUE; 447174e2c79eSStefano Zampini } else { 44726e683305SStefano Zampini csin_ds = PETSC_FALSE; 44736e683305SStefano Zampini ncoarse_ds = all_procs; 44746e683305SStefano Zampini } 44756e683305SStefano Zampini } 447674e2c79eSStefano Zampini } 44776e683305SStefano Zampini 44786e683305SStefano Zampini /* 44796e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 44806e683305SStefano Zampini - we have not exceeded the number of levels requested 44816e683305SStefano Zampini - we can actually subassemble the active processes 44826e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 44836e683305SStefano Zampini */ 44846e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 44856e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 44866e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 44876e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 44886e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4489f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 44902b510759SStefano Zampini } else { 4491f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4492c8587f34SStefano Zampini } 4493c8587f34SStefano Zampini } 44946e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 44956e683305SStefano Zampini if (multilevel_allowed) { 44966e683305SStefano Zampini ncoarse = ncoarse_ml; 44976e683305SStefano Zampini csin = csin_ml; 449858da7f69SStefano Zampini redist = PETSC_FALSE; 44996e683305SStefano Zampini } else { 45006e683305SStefano Zampini ncoarse = ncoarse_ds; 45016e683305SStefano Zampini csin = csin_ds; 45026e683305SStefano Zampini } 4503e7931f94SStefano Zampini 4504abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4505abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4506abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4507abbbba34SStefano Zampini 4508abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 450922bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 451022bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 451122bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 451222bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4513b1ecc7b1SStefano Zampini #if 0 4514b9b85e73SStefano Zampini { 4515b9b85e73SStefano Zampini PetscViewer viewer; 4516b9b85e73SStefano Zampini char filename[256]; 4517b1ecc7b1SStefano Zampini sprintf(filename,"local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4518b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4519b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4520b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 4521b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4522b9b85e73SStefano Zampini } 4523b9b85e73SStefano Zampini #endif 4524e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)pc),1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_islg,NULL,&t_coarse_mat_is);CHKERRQ(ierr); 45256e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 45266e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45276e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4528abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4529abbbba34SStefano Zampini 45306e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 45316e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 45326e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 45336e683305SStefano Zampini const PetscInt *idxs; 45346e683305SStefano Zampini ISLocalToGlobalMapping tmap; 45356e683305SStefano Zampini 45366e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 45370be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 45386e683305SStefano Zampini /* allocate space for temporary storage */ 4539854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4540854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 45416e683305SStefano Zampini /* allocate for IS array */ 45426e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 45436e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 45446e683305SStefano Zampini nis = nisdofs + nisneu; 4545854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 45466e683305SStefano Zampini /* dofs splitting */ 45476e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 45486e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 45496e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 45506e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 45516e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 45526e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 45536e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 45546e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 45556e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 45566e683305SStefano Zampini } 45576e683305SStefano Zampini /* neumann boundaries */ 45586e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 45596e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 45606e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 45616e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 45626e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 45636e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 45646e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 45656e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 45666e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 45676e683305SStefano Zampini } 45686e683305SStefano Zampini /* free memory */ 45696e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 45706e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 45716e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 45726e683305SStefano Zampini } else { 45736e683305SStefano Zampini nis = 0; 45746e683305SStefano Zampini nisdofs = 0; 45756e683305SStefano Zampini nisneu = 0; 45766e683305SStefano Zampini isarray = NULL; 45776e683305SStefano Zampini } 45786e683305SStefano Zampini /* destroy no longer needed map */ 45796e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 45806e683305SStefano Zampini 45816e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 45826e683305SStefano Zampini coarse_mat_is = NULL; 45836e683305SStefano Zampini if (csin) { 45846e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 458574e2c79eSStefano Zampini if (redist) { 458674e2c79eSStefano Zampini PetscMPIInt rank; 4587779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 458874e2c79eSStefano Zampini 458974e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 459058da7f69SStefano Zampini spc = active_procs/ncoarse; 459158da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 4592779c1cceSStefano Zampini if (im_active) { 4593779c1cceSStefano Zampini destsize = 1; 459474e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 459574e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 459674e2c79eSStefano Zampini } else { 459774e2c79eSStefano Zampini dest[0] = rank/(spc+1); 459874e2c79eSStefano Zampini } 459974e2c79eSStefano Zampini } else { 4600779c1cceSStefano Zampini destsize = 0; 46016e683305SStefano Zampini } 4602779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4603779c1cceSStefano Zampini } else if (csin_type_simple) { 46046e683305SStefano Zampini PetscMPIInt rank; 46056e683305SStefano Zampini PetscInt issize,isidx; 4606779c1cceSStefano Zampini 46076e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 46086e683305SStefano Zampini if (im_active) { 46096e683305SStefano Zampini issize = 1; 46106e683305SStefano Zampini isidx = (PetscInt)rank; 46116e683305SStefano Zampini } else { 46126e683305SStefano Zampini issize = 0; 46136e683305SStefano Zampini isidx = -1; 46146e683305SStefano Zampini } 46156e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4616779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 4617b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 46186e683305SStefano Zampini } 4619779c1cceSStefano Zampini 4620779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 4621779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 4622779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 4623779c1cceSStefano Zampini PetscInt *coarse_candidates; 4624779c1cceSStefano Zampini const PetscInt* tisindices; 4625779c1cceSStefano Zampini 4626779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 4627779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 4628779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4629779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 4630779c1cceSStefano Zampini if (!coarse_candidates[i]) { 4631779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 4632779c1cceSStefano Zampini } 4633779c1cceSStefano Zampini } 4634779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 4635779c1cceSStefano Zampini 4636779c1cceSStefano Zampini 46376e683305SStefano Zampini if (pcbddc->dbg_flag) { 46386e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 46396e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 46406e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 46416e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 4642779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 46436e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 46446e683305SStefano Zampini } 46456e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 46466e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 46476e683305SStefano Zampini } 46486e683305SStefano Zampini /* shift the pattern on coarse candidates */ 46496e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 46506e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 4651854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 46526e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 46536e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 46546e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 46556e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 46566e683305SStefano Zampini } 46576e683305SStefano Zampini if (pcbddc->dbg_flag) { 46586e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 46596e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 46606e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 46616e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 46626e683305SStefano Zampini } 4663779c1cceSStefano Zampini } 46646e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 466553a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 466653a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_FALSE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 466753a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 466853a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 466953a05cb3SStefano Zampini } 46706e683305SStefano Zampini } else { 46716e683305SStefano Zampini if (pcbddc->dbg_flag) { 46726e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 46736e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 46746e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 46756e683305SStefano Zampini } 46766e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 46776e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 46786e683305SStefano Zampini } 46796e683305SStefano Zampini 46806e683305SStefano Zampini /* create local to global scatters for coarse problem */ 468168457ee5SStefano Zampini if (compute_vecs) { 46826e683305SStefano Zampini PetscInt lrows; 46836e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 46846e683305SStefano Zampini if (coarse_mat_is) { 46856e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 46866e683305SStefano Zampini } else { 46876e683305SStefano Zampini lrows = 0; 46886e683305SStefano Zampini } 46896e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 46906e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 46916e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 46926e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 46936e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 46946e683305SStefano Zampini } 46956e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 46966e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 4697c8587f34SStefano Zampini 4698f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 4699f9eb5b7dSStefano Zampini if (multilevel_allowed) { 4700f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 4701f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 4702f9eb5b7dSStefano Zampini } else { 4703f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 4704f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 4705c8587f34SStefano Zampini } 4706c8587f34SStefano Zampini 47076e683305SStefano Zampini /* print some info if requested */ 47086e683305SStefano Zampini if (pcbddc->dbg_flag) { 47096e683305SStefano Zampini if (!multilevel_allowed) { 47106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47116e683305SStefano Zampini if (multilevel_requested) { 47126e683305SStefano 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); 47136e683305SStefano Zampini } else if (pcbddc->max_levels) { 47146e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 47156e683305SStefano Zampini } 47166e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47176e683305SStefano Zampini } 47186e683305SStefano Zampini } 47196e683305SStefano Zampini 4720f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 47216e683305SStefano Zampini if (coarse_mat_is) { 47226e683305SStefano Zampini MatReuse coarse_mat_reuse; 47236a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 47246e683305SStefano Zampini if (pcbddc->dbg_flag) { 47256e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 47266e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 47276e683305SStefano Zampini } 4728f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 4729312be037SStefano Zampini char prefix[256],str_level[16]; 4730e604994aSStefano Zampini size_t len; 47316e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 4732422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 4733c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 4734f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 47355f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 4736c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 47376e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 4738c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4739c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4740e604994aSStefano Zampini /* prefix */ 4741e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 4742e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4743e604994aSStefano Zampini if (!pcbddc->current_level) { 4744e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4745e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 4746c8587f34SStefano Zampini } else { 4747e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4748312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4749312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 475034d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4751312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4752e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 4753e604994aSStefano Zampini } 4754e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 47553e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 47563e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 47573e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 47583e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 4759f9eb5b7dSStefano Zampini /* allow user customization */ 4760f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 47613e3c6dadSStefano Zampini } 47623e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 476351bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 47643e3c6dadSStefano Zampini if (nisdofs) { 47653e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 47663e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 47673e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 47683e3c6dadSStefano Zampini } 47693e3c6dadSStefano Zampini } 47703e3c6dadSStefano Zampini if (nisneu) { 47713e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 47723e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 4773312be037SStefano Zampini } 4774f9eb5b7dSStefano Zampini 4775f9eb5b7dSStefano Zampini /* get some info after set from options */ 4776f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 4777f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 47784f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 47796e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 4780f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4781f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 4782f9eb5b7dSStefano Zampini } 478339f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 47844f3a063dSStefano Zampini if (isredundant) { 47854f3a063dSStefano Zampini KSP inner_ksp; 47864f3a063dSStefano Zampini PC inner_pc; 47874f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 47884f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 47894f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 47904f3a063dSStefano Zampini } 4791f9eb5b7dSStefano Zampini 4792f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 4793fa7f1dd8SStefano Zampini if (coarse_reuse) { 479481d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 4795fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 47966e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 4797fa7f1dd8SStefano Zampini } else { 47986e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 4799fa7f1dd8SStefano Zampini } 4800c8587f34SStefano Zampini if (isbddc || isnn) { 480122bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 480270cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 4803b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 480422b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 48056e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 48066e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 48076e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 48086e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 480922b6e8a2SStefano Zampini } 481070cf5478SStefano Zampini } 481153a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 481270cf5478SStefano Zampini } else { 481322bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 481422bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 481522bc73bbSStefano Zampini } 481622bc73bbSStefano Zampini } else { 48172e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 4818c8587f34SStefano Zampini } 4819c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 4820c8587f34SStefano Zampini 48213301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 48225a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 48233301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 48243301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 48253301b35fSStefano Zampini } 48263301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 48273301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 48283301b35fSStefano Zampini } 48293301b35fSStefano Zampini if (pc->pmat->spd_set) { 48303301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 48313301b35fSStefano Zampini } 48326e683305SStefano Zampini /* set operators */ 48335f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 48346e683305SStefano Zampini if (pcbddc->dbg_flag) { 48356e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 48366e683305SStefano Zampini } 48376e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 48386e683305SStefano Zampini coarse_mat = 0; 48396e683305SStefano Zampini } 48406e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 4841b1ecc7b1SStefano Zampini #if 0 4842b9b85e73SStefano Zampini { 4843b9b85e73SStefano Zampini PetscViewer viewer; 4844b9b85e73SStefano Zampini char filename[256]; 4845b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 4846b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 4847b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4848b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 4849b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4850b9b85e73SStefano Zampini } 4851b9b85e73SStefano Zampini #endif 4852c8587f34SStefano Zampini 4853c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 4854298c0119SStefano Zampini #if 0 4855c8587f34SStefano Zampini if (pcbddc->NullSpace) { 4856c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 485798a51de6SStefano Zampini } 4858298c0119SStefano Zampini #endif 485998a51de6SStefano Zampini 486098a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 486198a51de6SStefano Zampini Vec crhs,csol; 486298a51de6SStefano Zampini PetscBool ispreonly; 486304708bb6SStefano Zampini 486498a51de6SStefano Zampini if (CoarseNullSpace) { 4865c8587f34SStefano Zampini if (isbddc) { 4866c8587f34SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4867c8587f34SStefano Zampini } else { 48685fa7ec2dSBarry Smith ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 4869c8587f34SStefano Zampini } 4870c8587f34SStefano Zampini } 4871f9eb5b7dSStefano Zampini /* setup coarse ksp */ 4872f9eb5b7dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4873f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4874f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 48756e683305SStefano Zampini /* hack */ 4876f347579bSStefano Zampini if (!csol) { 48772a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4878f9eb5b7dSStefano Zampini } 4879f347579bSStefano Zampini if (!crhs) { 48802a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4881f347579bSStefano Zampini } 4882cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4883cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 48846e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4885c8587f34SStefano Zampini KSP check_ksp; 48862b510759SStefano Zampini KSPType check_ksp_type; 4887c8587f34SStefano Zampini PC check_pc; 48886e683305SStefano Zampini Vec check_vec,coarse_vec; 48896a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 48902b510759SStefano Zampini PetscInt its; 48916e683305SStefano Zampini PetscBool compute_eigs; 48926e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 48936e683305SStefano Zampini PetscInt neigs; 48948e185a42SStefano Zampini const char *prefix; 4895c8587f34SStefano Zampini 48962b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 48976e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 4898422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 489923ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4900f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 49012b510759SStefano Zampini if (ispreonly) { 49022b510759SStefano Zampini check_ksp_type = KSPPREONLY; 49036e683305SStefano Zampini compute_eigs = PETSC_FALSE; 49042b510759SStefano Zampini } else { 4905cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 49066e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4907c8587f34SStefano Zampini } 4908c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 49096e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 49106e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 49116e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 4912a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 4913a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 4914a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 4915a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 4916c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4917c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4918c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4919c8587f34SStefano Zampini /* create random vec */ 49206e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 49216e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 4922c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 4923c8587f34SStefano Zampini if (CoarseNullSpace) { 4924c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 4925c8587f34SStefano Zampini } 49266e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 4927c8587f34SStefano Zampini /* solve coarse problem */ 49286e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 4929c8587f34SStefano Zampini if (CoarseNullSpace) { 49306e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 4931c8587f34SStefano Zampini } 4932cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 49336e683305SStefano Zampini if (compute_eigs) { 4934854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 4935854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 49366e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 49376e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 49386e683305SStefano Zampini lambda_min = eigs_r[0]; 49396e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 49406e683305SStefano Zampini if (lambda_max>lambda_min) { 4941cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 4942cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 4943cbcc2c2aSStefano Zampini } 4944c8587f34SStefano Zampini } 4945c8587f34SStefano Zampini } 4946cbcc2c2aSStefano Zampini 4947c8587f34SStefano Zampini /* check coarse problem residual error */ 49486e683305SStefano Zampini if (pcbddc->dbg_flag) { 49496e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 49506e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 49516e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 4952c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 49536e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 49546e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 4955c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 4956779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 49576e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 49586e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 49596e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 49606e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 49616e683305SStefano Zampini if (compute_eigs) { 49626e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 4963deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 4964c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 49656e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 49666e683305SStefano 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); 49676e683305SStefano Zampini for (i=0;i<neigs;i++) { 49686e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 4969c8587f34SStefano Zampini } 49706e683305SStefano Zampini } 49716e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 49726e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 49736e683305SStefano Zampini } 4974c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 49756e683305SStefano Zampini if (compute_eigs) { 49766e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 49776e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 4978c8587f34SStefano Zampini } 49796e683305SStefano Zampini } 49806e683305SStefano Zampini } 4981cbcc2c2aSStefano Zampini /* print additional info */ 4982cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 49836e683305SStefano Zampini /* waits until all processes reaches this point */ 49846e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 4985cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 4986cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4987cbcc2c2aSStefano Zampini } 4988cbcc2c2aSStefano Zampini 49892b510759SStefano Zampini /* free memory */ 4990c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4991fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 4992c8587f34SStefano Zampini PetscFunctionReturn(0); 4993c8587f34SStefano Zampini } 4994674ae819SStefano Zampini 4995f34684f1SStefano Zampini #undef __FUNCT__ 4996f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 4997f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 4998f34684f1SStefano Zampini { 4999f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5000f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5001f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5002dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5003dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 500473be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5005dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5006f34684f1SStefano Zampini PetscErrorCode ierr; 5007f34684f1SStefano Zampini 5008f34684f1SStefano Zampini PetscFunctionBegin; 5009f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 50100e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 50110e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5012727cdba6SStefano Zampini } 5013dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 50143bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5015dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5016dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5017dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5018dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5019dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5020dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 50210e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 50220e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 50230e6343abSStefano Zampini } 5024dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5025dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5026dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5027dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5028dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5029f34684f1SStefano Zampini 5030f34684f1SStefano Zampini /* check numbering */ 5031f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5032019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5033dc456d91SStefano Zampini PetscInt i; 5034b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5035f34684f1SStefano Zampini 5036f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5037f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5038f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 50390fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 5040019a44ceSStefano Zampini /* counter */ 5041019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5042019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5043019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5044019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5045019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5046019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5047019a44ceSStefano Zampini 5048f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5049f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5050727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5051f34684f1SStefano Zampini } 5052f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5053f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5054f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5055e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5056e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5057e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5058e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5059f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5060019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5061f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5062019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 5063019a44ceSStefano Zampini PetscInt owned = (PetscInt)(array[i]); 5064019a44ceSStefano Zampini PetscInt neigh = (PetscInt)(array2[i]); 5065b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5066019a44ceSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a %d processes instead of %d!\n",PetscGlobalRank,i,owned,neigh);CHKERRQ(ierr); 5067f34684f1SStefano Zampini } 5068f34684f1SStefano Zampini } 5069019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5070b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5071f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5072f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5073f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5074f34684f1SStefano Zampini } 5075f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5076f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5077e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5078e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5079f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5080f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5081b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5082ca8b9ea9SStefano Zampini PetscInt *gidxs; 5083ca8b9ea9SStefano Zampini 5084ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 50853bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5086f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5087f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5088f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5089f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 50904bc2dc4bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d,%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i],gidxs[i]);CHKERRQ(ierr); 5091f34684f1SStefano Zampini } 5092f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5093ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5094f34684f1SStefano Zampini } 5095f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5096302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5097f34684f1SStefano Zampini } 50988bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5099f34684f1SStefano Zampini /* get back data */ 5100f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5101f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5102674ae819SStefano Zampini PetscFunctionReturn(0); 5103674ae819SStefano Zampini } 5104674ae819SStefano Zampini 5105e456f2a8SStefano Zampini #undef __FUNCT__ 5106e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5107a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5108e456f2a8SStefano Zampini { 5109e456f2a8SStefano Zampini IS localis_t; 5110a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5111e456f2a8SStefano Zampini PetscScalar *vals; 5112e456f2a8SStefano Zampini PetscErrorCode ierr; 5113e456f2a8SStefano Zampini 5114e456f2a8SStefano Zampini PetscFunctionBegin; 5115a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5116e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5117854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5118e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5119e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5120a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5121a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 51221035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5123a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 51241035eff8SStefano Zampini } 5125a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5126e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5127e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5128a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5129a7dc3881SStefano Zampini /* now compute set in local ordering */ 5130a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5131a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5132a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5133a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5134a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5135ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5136e456f2a8SStefano Zampini lsize++; 5137e456f2a8SStefano Zampini } 5138e456f2a8SStefano Zampini } 5139854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5140a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5141ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5142e456f2a8SStefano Zampini idxs[lsize++] = i; 5143e456f2a8SStefano Zampini } 5144e456f2a8SStefano Zampini } 5145a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5146a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5147e456f2a8SStefano Zampini *localis = localis_t; 5148e456f2a8SStefano Zampini PetscFunctionReturn(0); 5149e456f2a8SStefano Zampini } 5150906d46d4SStefano Zampini 5151906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5152906d46d4SStefano Zampini #undef __FUNCT__ 5153906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5154906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5155906d46d4SStefano Zampini { 5156906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5157906d46d4SStefano Zampini PetscErrorCode ierr; 5158906d46d4SStefano Zampini 5159906d46d4SStefano Zampini PetscFunctionBegin; 5160906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5161906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5162906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5163906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5164906d46d4SStefano Zampini PetscFunctionReturn(0); 5165906d46d4SStefano Zampini } 5166906d46d4SStefano Zampini 5167906d46d4SStefano Zampini #undef __FUNCT__ 5168906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5169906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5170906d46d4SStefano Zampini { 5171906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5172906d46d4SStefano Zampini PetscErrorCode ierr; 5173906d46d4SStefano Zampini 5174906d46d4SStefano Zampini PetscFunctionBegin; 5175906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5176906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5177906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5178906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5179906d46d4SStefano Zampini PetscFunctionReturn(0); 5180906d46d4SStefano Zampini } 5181b96c3477SStefano Zampini 5182b96c3477SStefano Zampini #undef __FUNCT__ 5183b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 518408122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5185b96c3477SStefano Zampini { 5186a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5187b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5188b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5189a64f4aa4SStefano Zampini Mat S_j; 5190b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 5191b96c3477SStefano Zampini PetscBool free_used_adj; 5192b96c3477SStefano Zampini PetscErrorCode ierr; 5193b96c3477SStefano Zampini 5194b96c3477SStefano Zampini PetscFunctionBegin; 5195b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 5196b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 519708122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 5198b96c3477SStefano Zampini used_xadj = NULL; 5199b96c3477SStefano Zampini used_adjncy = NULL; 5200b96c3477SStefano Zampini } else { 520108122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 520208122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 520308122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 520408122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 5205b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 5206b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 5207b96c3477SStefano Zampini } else { 52082fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 5209b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 5210b96c3477SStefano Zampini PetscInt nvtxs; 5211b96c3477SStefano Zampini 52122fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 52132fffb893SStefano Zampini if (flg_row) { 5214b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 5215b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 5216b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 5217b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 52182fffb893SStefano Zampini } else { 52192fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 52202fffb893SStefano Zampini used_xadj = NULL; 52212fffb893SStefano Zampini used_adjncy = NULL; 52222fffb893SStefano Zampini } 52232fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 5224b96c3477SStefano Zampini } 5225b96c3477SStefano Zampini } 5226d5574798SStefano Zampini 5227d5574798SStefano Zampini /* setup sub_schurs data */ 5228a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5229a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 5230a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 5231a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 523206a4e24aSStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,NULL,S_j,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,PETSC_FALSE,PETSC_FALSE);CHKERRQ(ierr); 5233a64f4aa4SStefano Zampini } else { 52346816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 523504708bb6SStefano Zampini PetscBool isseqaij; 52365feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 52375feab87aSStefano Zampini PetscInt n_vertices; 52385feab87aSStefano Zampini 52395feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 52402034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 52415feab87aSStefano Zampini } 524204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 524304708bb6SStefano Zampini if (!isseqaij) { 524404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 524504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 524604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 524704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 524804708bb6SStefano Zampini } else { 524904708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 525004708bb6SStefano Zampini } 525104708bb6SStefano Zampini } 525206a4e24aSStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,pcbddc->local_mat,S_j,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,reuse_solvers,pcbddc->benign_saddle_point);CHKERRQ(ierr); 5253a64f4aa4SStefano Zampini } 5254a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5255b96c3477SStefano Zampini 5256b96c3477SStefano Zampini /* free adjacency */ 5257b96c3477SStefano Zampini if (free_used_adj) { 5258b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 5259b96c3477SStefano Zampini } 5260b96c3477SStefano Zampini PetscFunctionReturn(0); 5261b96c3477SStefano Zampini } 5262b96c3477SStefano Zampini 5263b96c3477SStefano Zampini #undef __FUNCT__ 5264b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 526508122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 5266b96c3477SStefano Zampini { 5267b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5268b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5269b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5270b96c3477SStefano Zampini PCBDDCGraph graph; 5271b96c3477SStefano Zampini PetscErrorCode ierr; 5272b96c3477SStefano Zampini 5273b96c3477SStefano Zampini PetscFunctionBegin; 5274b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 527508122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 52763301b35fSStefano Zampini IS verticesIS,verticescomm; 52773301b35fSStefano Zampini PetscInt vsize,*idxs; 5278b96c3477SStefano Zampini 5279b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 52803301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 52813301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 52823301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 52833301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 52843301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 5285b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 52867fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 52873301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 52883301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 5289b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5290b96c3477SStefano Zampini /* 5291b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 5292b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5293b96c3477SStefano Zampini } 5294b96c3477SStefano Zampini */ 5295b96c3477SStefano Zampini } else { 5296b96c3477SStefano Zampini graph = pcbddc->mat_graph; 5297b96c3477SStefano Zampini } 5298b96c3477SStefano Zampini 5299b96c3477SStefano Zampini /* sub_schurs init */ 5300a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 5301a64f4aa4SStefano Zampini 5302b96c3477SStefano Zampini /* free graph struct */ 530308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 5304b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 5305b96c3477SStefano Zampini } 5306b96c3477SStefano Zampini PetscFunctionReturn(0); 5307b96c3477SStefano Zampini } 5308