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__ 95408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 105408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 115408967cSStefano Zampini { 125408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 135408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 14dee84bffSStefano Zampini IS dirIS = NULL; 155408967cSStefano Zampini PetscErrorCode ierr; 165408967cSStefano Zampini 175408967cSStefano Zampini PetscFunctionBegin; 18dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 195408967cSStefano Zampini if (zerodiag) { 205408967cSStefano Zampini Mat A; 215408967cSStefano Zampini Vec vec3_N; 225408967cSStefano Zampini PetscScalar *vals; 235408967cSStefano Zampini const PetscInt *idxs; 245408967cSStefano Zampini PetscInt i,nz; 255408967cSStefano Zampini 265408967cSStefano Zampini /* p0 */ 275408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 285408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 295408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 305408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 315408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; /* TODO add quadrature */ 325408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 335408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 345408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 355408967cSStefano Zampini /* v_I */ 365408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 375408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 385408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 395408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 405408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 415408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 425408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 435408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 445408967cSStefano Zampini if (dirIS) { 455408967cSStefano Zampini PetscInt n; 465408967cSStefano Zampini 475408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 485408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 495408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 505408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 515408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 525408967cSStefano Zampini } 535408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 545408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 555408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 565408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 575408967cSStefano Zampini ierr = MatISGetLocalMat(pc->mat,&A);CHKERRQ(ierr); 585408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 595408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 605408967cSStefano Zampini if (PetscAbsScalar(vals[0]) > PETSC_SMALL) { /* TODO: should I add the A-norm in test? */ 615408967cSStefano 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])); 625408967cSStefano Zampini } 635408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 645408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 655408967cSStefano Zampini } 66dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 675408967cSStefano Zampini 685408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 695408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 705408967cSStefano Zampini pcbddc->benign_p0 = -PetscGlobalRank; 715408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 725408967cSStefano Zampini pcbddc->benign_p0 = 1; 735408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 745408967cSStefano Zampini if (pcbddc->benign_p0_gidx >=0 && pcbddc->benign_p0 != -PetscGlobalRank) { 755408967cSStefano 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); 765408967cSStefano Zampini } 775408967cSStefano Zampini PetscFunctionReturn(0); 785408967cSStefano Zampini } 795408967cSStefano Zampini 805408967cSStefano Zampini #undef __FUNCT__ 81339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 82339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 83339f8db1SStefano Zampini { 84339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8540fa8d13SStefano Zampini IS pressures,zerodiag; 86*b0f5fe93SStefano Zampini PetscInt nz,n; 87*b0f5fe93SStefano Zampini PetscBool sorted,have_null; 88339f8db1SStefano Zampini PetscErrorCode ierr; 89339f8db1SStefano Zampini 90339f8db1SStefano Zampini PetscFunctionBegin; 91339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 92339f8db1SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->local_mat);CHKERRQ(ierr); 93339f8db1SStefano Zampini pcbddc->benign_original_mat = pcbddc->local_mat; 9440fa8d13SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures", otherwise, uses only zerodiagonal dofs (ok if the pressure block is all zero) */ 9540fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 9640fa8d13SStefano Zampini PetscInt p = pcbddc->n_ISForDofsLocal-1; 9740fa8d13SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[p]);CHKERRQ(ierr); 9840fa8d13SStefano Zampini pressures = pcbddc->ISForDofsLocal[p]; 9940fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 10040fa8d13SStefano Zampini if (!sorted) { 10140fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 10240fa8d13SStefano Zampini } 10340fa8d13SStefano Zampini } else { 10440fa8d13SStefano Zampini pressures = NULL; 10540fa8d13SStefano Zampini } 106339f8db1SStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->benign_original_mat,&zerodiag);CHKERRQ(ierr); 107339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 108339f8db1SStefano Zampini if (!sorted) { 109339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 110339f8db1SStefano Zampini } 11140fa8d13SStefano Zampini /* 11240fa8d13SStefano Zampini Check if all the pressure dofs have a zero diagonal 11340fa8d13SStefano Zampini If not, a change of basis on pressures is not needed 11440fa8d13SStefano Zampini since the local Schur complements are SPD 11540fa8d13SStefano Zampini */ 116339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 11740fa8d13SStefano Zampini if (pressures) { 11840fa8d13SStefano Zampini PetscInt np; 11940fa8d13SStefano Zampini PetscBool sameis; 12040fa8d13SStefano Zampini 12140fa8d13SStefano Zampini sameis = PETSC_FALSE; 12240fa8d13SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 12340fa8d13SStefano Zampini if (nz == np) { 12440fa8d13SStefano Zampini const PetscInt *idxs,*pidxs; 12540fa8d13SStefano Zampini 12640fa8d13SStefano Zampini ierr = ISGetIndices(pressures,&pidxs);CHKERRQ(ierr); 12740fa8d13SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 12840fa8d13SStefano Zampini ierr = PetscMemcmp(pidxs,idxs,np*sizeof(PetscInt),&sameis);CHKERRQ(ierr); 12940fa8d13SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 13040fa8d13SStefano Zampini ierr = ISRestoreIndices(pressures,&pidxs);CHKERRQ(ierr); 13140fa8d13SStefano Zampini } 13240fa8d13SStefano Zampini if (!sameis) { /* destroy index sets and set nz to 0 to avoid next code branch */ 13340fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 13440fa8d13SStefano Zampini nz = 0; 13540fa8d13SStefano Zampini } 13640fa8d13SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 13740fa8d13SStefano Zampini } 138339f8db1SStefano Zampini if (nz) { 139339f8db1SStefano Zampini IS zerodiagc; 140339f8db1SStefano Zampini PetscScalar *array; 141339f8db1SStefano Zampini const PetscInt *idxs,*idxsc; 142*b0f5fe93SStefano Zampini PetscInt i,*nnz; 143339f8db1SStefano Zampini 144339f8db1SStefano Zampini /* TODO: add check for shared dofs and raise error */ 145339f8db1SStefano Zampini ierr = MatGetLocalSize(pcbddc->benign_original_mat,&n,NULL);CHKERRQ(ierr); 146339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 147339f8db1SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 148339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 149339f8db1SStefano Zampini /* local change of basis for pressures */ 150339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 151339f8db1SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->benign_original_mat),&pcbddc->benign_change);CHKERRQ(ierr); 152339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 153339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 154339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 155339f8db1SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities */ 156339f8db1SStefano Zampini for (i=0;i<nz-1;i++) nnz[idxs[i]] = 2; /* change on pressures */ 157339f8db1SStefano Zampini nnz[idxs[nz-1]] = nz; /* last local pressure dof: _0 set */ 158339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 159339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 160339f8db1SStefano Zampini /* set identity on velocities */ 161339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 162339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 163339f8db1SStefano Zampini } 164339f8db1SStefano Zampini /* set change on pressures */ 165339f8db1SStefano Zampini for (i=0;i<nz-1;i++) { 166339f8db1SStefano Zampini PetscScalar vals[2]; 167339f8db1SStefano Zampini PetscInt cols[2]; 168339f8db1SStefano Zampini 169339f8db1SStefano Zampini /* TODO: add quadrature */ 170339f8db1SStefano Zampini cols[0] = idxs[i]; 171339f8db1SStefano Zampini cols[1] = idxs[nz-1]; 172339f8db1SStefano Zampini vals[0] = 1.; 173*b0f5fe93SStefano Zampini vals[1] = 1.; 174339f8db1SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+i,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 175339f8db1SStefano Zampini } 176339f8db1SStefano Zampini ierr = PetscMalloc1(nz,&array);CHKERRQ(ierr); 177339f8db1SStefano Zampini for (i=0;i<nz-1;i++) array[i] = -1.; 178*b0f5fe93SStefano Zampini array[nz-1] = 1.; 179339f8db1SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nz-1,nz,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 180339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 181339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 182339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 183339f8db1SStefano Zampini /* TODO: need optimization? */ 184339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 185339f8db1SStefano Zampini ierr = MatPtAP(pcbddc->benign_original_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 186339f8db1SStefano Zampini /* store local and global idxs for p0 */ 187339f8db1SStefano Zampini pcbddc->benign_p0_lidx = idxs[nz-1]; 188339f8db1SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,1,&idxs[nz-1],&pcbddc->benign_p0_gidx);CHKERRQ(ierr); 189339f8db1SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 190339f8db1SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 191339f8db1SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 192*b0f5fe93SStefano Zampini } else { /* if nz == 0, destroy local IS */ 193*b0f5fe93SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 194339f8db1SStefano Zampini } 195*b0f5fe93SStefano Zampini 196*b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 197*b0f5fe93SStefano Zampini ierr = MatGetLocalSize(pcbddc->benign_original_mat,&n,NULL);CHKERRQ(ierr); 198*b0f5fe93SStefano Zampini have_null = PETSC_TRUE; 199*b0f5fe93SStefano Zampini if (!zerodiag && n) have_null = PETSC_FALSE; 200*b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 201339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 202339f8db1SStefano Zampini PetscFunctionReturn(0); 203339f8db1SStefano Zampini } 204339f8db1SStefano Zampini 205339f8db1SStefano Zampini #undef __FUNCT__ 206015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 207015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 208efc2fbd9SStefano Zampini { 209efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 210efc2fbd9SStefano Zampini PetscErrorCode ierr; 211efc2fbd9SStefano Zampini 212efc2fbd9SStefano Zampini PetscFunctionBegin; 213efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 214efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 215c9ed8603SStefano Zampini if (pcbddc->benign_p0_gidx >= 0) { 216efc2fbd9SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,1,NULL,PETSC_OWN_POINTER,&pcbddc->benign_p0_gidx);CHKERRQ(ierr); 217c9ed8603SStefano Zampini } else { 218c9ed8603SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,0,NULL,PETSC_OWN_POINTER,&pcbddc->benign_p0_gidx);CHKERRQ(ierr); 219c9ed8603SStefano Zampini } 220efc2fbd9SStefano Zampini } 221015636ebSStefano Zampini if (get) { /* use SF to get values */ 222efc2fbd9SStefano Zampini PetscScalar *array; 223efc2fbd9SStefano Zampini 224efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 225efc2fbd9SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,&pcbddc->benign_p0);CHKERRQ(ierr); 226efc2fbd9SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,&pcbddc->benign_p0);CHKERRQ(ierr); 227efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 228efc2fbd9SStefano Zampini } else { /* use VecSetValue */ 229c9ed8603SStefano Zampini if (pcbddc->benign_p0_gidx >= 0) { 230efc2fbd9SStefano Zampini ierr = VecSetValue(v,pcbddc->benign_p0_gidx,pcbddc->benign_p0,INSERT_VALUES);CHKERRQ(ierr); 231c9ed8603SStefano Zampini } 232efc2fbd9SStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 233efc2fbd9SStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 234efc2fbd9SStefano Zampini } 235efc2fbd9SStefano Zampini PetscFunctionReturn(0); 236efc2fbd9SStefano Zampini } 237efc2fbd9SStefano Zampini 238efc2fbd9SStefano Zampini #undef __FUNCT__ 239c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 240c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 241c263805aSStefano Zampini { 242c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 243c263805aSStefano Zampini PetscErrorCode ierr; 244c263805aSStefano Zampini 245c263805aSStefano Zampini PetscFunctionBegin; 246c263805aSStefano Zampini /* TODO: add error checking 247c263805aSStefano Zampini - avoid nested pop (or push) calls. 248c263805aSStefano Zampini - cannot push before pop. 2491c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 250c263805aSStefano Zampini */ 251c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx < 0) { 252efc2fbd9SStefano Zampini PetscFunctionReturn(0); 253efc2fbd9SStefano Zampini } 254c263805aSStefano Zampini if (pop) { 255c263805aSStefano Zampini const PetscInt *cB0_cols; 256c263805aSStefano Zampini PetscInt cB0_ncol; 257c263805aSStefano Zampini const PetscScalar *cB0_vals; 258c263805aSStefano Zampini 259c263805aSStefano Zampini /* extract B_0 */ 260efc2fbd9SStefano Zampini ierr = MatGetRow(pcbddc->local_mat,pcbddc->benign_p0_lidx,&cB0_ncol,&cB0_cols,&cB0_vals);CHKERRQ(ierr); 261c263805aSStefano Zampini pcbddc->B0_ncol = cB0_ncol; 262c263805aSStefano Zampini ierr = PetscFree2(pcbddc->B0_cols,pcbddc->B0_vals);CHKERRQ(ierr); 263c263805aSStefano Zampini ierr = PetscMalloc2(cB0_ncol,&pcbddc->B0_cols,cB0_ncol,&pcbddc->B0_vals);CHKERRQ(ierr); 264c263805aSStefano Zampini ierr = PetscMemcpy(pcbddc->B0_cols,cB0_cols,cB0_ncol*sizeof(PetscInt));CHKERRQ(ierr); 265c263805aSStefano Zampini ierr = PetscMemcpy(pcbddc->B0_vals,cB0_vals,cB0_ncol*sizeof(PetscScalar));CHKERRQ(ierr); 266efc2fbd9SStefano Zampini ierr = MatRestoreRow(pcbddc->local_mat,pcbddc->benign_p0_lidx,&cB0_ncol,&cB0_cols,&cB0_vals);CHKERRQ(ierr); 267c263805aSStefano Zampini /* remove rows and cols from local problem */ 268c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 269efc2fbd9SStefano Zampini ierr = MatZeroRowsColumns(pcbddc->local_mat,1,&pcbddc->benign_p0_lidx,1.,NULL,NULL);CHKERRQ(ierr); 270c263805aSStefano Zampini } else { /* push */ 271efc2fbd9SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,&pcbddc->benign_p0_lidx,pcbddc->B0_ncol,pcbddc->B0_cols,pcbddc->B0_vals,INSERT_VALUES);CHKERRQ(ierr); 272efc2fbd9SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,pcbddc->B0_ncol,pcbddc->B0_cols,1,&pcbddc->benign_p0_lidx,pcbddc->B0_vals,INSERT_VALUES);CHKERRQ(ierr); 273efc2fbd9SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx,pcbddc->benign_p0_lidx,0.0,INSERT_VALUES);CHKERRQ(ierr); 274c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 275c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 276c263805aSStefano Zampini } 277c263805aSStefano Zampini PetscFunctionReturn(0); 278c263805aSStefano Zampini } 279c263805aSStefano Zampini 280c263805aSStefano Zampini #undef __FUNCT__ 281b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 28208122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 283b1b3d7a2SStefano Zampini { 284b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 28508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 28608122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 28708122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 28808122e43SStefano Zampini PetscScalar *work,lwork; 28908122e43SStefano Zampini PetscScalar *St,*S,*eigv; 29008122e43SStefano Zampini PetscScalar *Sarray,*Starray; 29108122e43SStefano Zampini PetscReal *eigs,thresh; 2921b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 293f6f667cfSStefano Zampini PetscBool allocated_S_St; 29408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 29508122e43SStefano Zampini PetscReal *rwork; 29608122e43SStefano Zampini #endif 297b1b3d7a2SStefano Zampini PetscErrorCode ierr; 298b1b3d7a2SStefano Zampini 299b1b3d7a2SStefano Zampini PetscFunctionBegin; 30008122e43SStefano Zampini if (!sub_schurs->use_mumps) { 30108122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS"); 30208122e43SStefano Zampini } 30308122e43SStefano Zampini 30406a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 30506a4e24aSStefano 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); 30606a4e24aSStefano Zampini } 30706a4e24aSStefano Zampini 308fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 309fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 310fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 311fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 312fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 313fd14bc51SStefano Zampini } 314fd14bc51SStefano Zampini 315e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 316e496cd5dSStefano 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); 317e496cd5dSStefano Zampini } 318e496cd5dSStefano Zampini 31908122e43SStefano Zampini /* max size of subsets */ 32008122e43SStefano Zampini mss = 0; 32108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 32208122e43SStefano Zampini PetscInt subset_size; 323862806e4SStefano Zampini 32408122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 32508122e43SStefano Zampini mss = PetscMax(mss,subset_size); 32608122e43SStefano Zampini } 32708122e43SStefano Zampini 32808122e43SStefano Zampini /* min/max and threshold */ 32908122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 330f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 33108122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 332f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 333f6f667cfSStefano Zampini if (nmin) { 334f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 335f6f667cfSStefano Zampini } 33608122e43SStefano Zampini 33708122e43SStefano Zampini /* allocate lapack workspace */ 33808122e43SStefano Zampini cum = cum2 = 0; 33908122e43SStefano Zampini maxneigs = 0; 34008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 34108122e43SStefano Zampini PetscInt n,subset_size; 342f6f667cfSStefano Zampini 34308122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 34408122e43SStefano Zampini n = PetscMin(subset_size,nmax); 3459162d606SStefano Zampini cum += subset_size; 3469162d606SStefano Zampini cum2 += subset_size*n; 34708122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 34808122e43SStefano Zampini } 34908122e43SStefano Zampini if (mss) { 3509ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 35108122e43SStefano Zampini PetscBLASInt B_itype = 1; 35208122e43SStefano Zampini PetscBLASInt B_N = mss; 3534c6709b3SStefano Zampini PetscReal zero = 0.0; 3544c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 35508122e43SStefano Zampini 35608122e43SStefano Zampini B_lwork = -1; 35708122e43SStefano Zampini S = NULL; 35808122e43SStefano Zampini St = NULL; 359a58a30b4SStefano Zampini eigs = NULL; 360a58a30b4SStefano Zampini eigv = NULL; 361a58a30b4SStefano Zampini B_iwork = NULL; 362a58a30b4SStefano Zampini B_ifail = NULL; 363d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 364d1710679SStefano Zampini rwork = NULL; 365d1710679SStefano Zampini #endif 3668bec7fa6SStefano Zampini thresh = 1.0; 36708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 36808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 36908122e43SStefano 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)); 37008122e43SStefano Zampini #else 37108122e43SStefano 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)); 37208122e43SStefano Zampini #endif 37308122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 37408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 37508122e43SStefano Zampini } else { 37608122e43SStefano Zampini /* TODO */ 37708122e43SStefano Zampini } 37808122e43SStefano Zampini } else { 37908122e43SStefano Zampini lwork = 0; 38008122e43SStefano Zampini } 38108122e43SStefano Zampini 38208122e43SStefano Zampini nv = 0; 383d62866d3SStefano 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) */ 384d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 38508122e43SStefano Zampini } 3864c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 387f6f667cfSStefano Zampini if (allocated_S_St) { 388f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 389f6f667cfSStefano Zampini } 390f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 39108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 39208122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 39308122e43SStefano Zampini #endif 3949162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 3959162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 3969162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 39708122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 3989162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 39908122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 40008122e43SStefano Zampini 40108122e43SStefano Zampini maxneigs = 0; 40208122e43SStefano Zampini cum = cum2 = cumarray = 0; 4039162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 4049162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 405d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 40608122e43SStefano Zampini const PetscInt *idxs; 40708122e43SStefano Zampini 408d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 40908122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 41008122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 41108122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 41208122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 4139162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 4149162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 41508122e43SStefano Zampini } 41608122e43SStefano Zampini cum2 = cum; 417d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 41808122e43SStefano Zampini } 41908122e43SStefano Zampini 42008122e43SStefano Zampini if (mss) { /* multilevel */ 42108122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 42208122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 42308122e43SStefano Zampini } 42408122e43SStefano Zampini 42508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 42608122e43SStefano Zampini 42708122e43SStefano Zampini const PetscInt *idxs; 428f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 429862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 43008122e43SStefano Zampini PetscBLASInt B_N; 431aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 43208122e43SStefano Zampini 433862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 434f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 435f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 4369ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 437aff50787SStefano Zampini PetscInt j,k; 438aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 439aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 440aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 44108122e43SStefano Zampini } 44208122e43SStefano Zampini for (j=0;j<subset_size;j++) { 443aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 444aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 445aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 446aff50787SStefano Zampini } 44708122e43SStefano Zampini } 44808122e43SStefano Zampini } else { 44908122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 45008122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 45108122e43SStefano Zampini } 4528bec7fa6SStefano Zampini } else { 453f6f667cfSStefano Zampini S = Sarray + cumarray; 454f6f667cfSStefano Zampini St = Starray + cumarray; 4558bec7fa6SStefano Zampini } 45608122e43SStefano Zampini 457f6f667cfSStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 458aff50787SStefano Zampini /* see if we can save some work */ 459aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 460aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 461aff50787SStefano Zampini } 462aff50787SStefano Zampini 463aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 464aff50787SStefano Zampini B_neigs = 0; 465aff50787SStefano Zampini } else { 466aff50787SStefano Zampini /* Threshold: this is an heuristic for edges */ 467f6f667cfSStefano Zampini thresh = pcbddc->mat_graph->count[idxs[0]]*pcbddc->adaptive_threshold; 468f6f667cfSStefano Zampini 4699ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 47008122e43SStefano Zampini PetscBLASInt B_itype = 1; 471f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 4724c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 4739552c7c7SStefano Zampini PetscInt nmin_s; 47408122e43SStefano Zampini 475fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 4768bec7fa6SStefano 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]]); 477fd14bc51SStefano Zampini } 478d16cbb6bSStefano Zampini 47908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 480d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 481d16cbb6bSStefano Zampini 482d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 48308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 484f6f667cfSStefano 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)); 48508122e43SStefano Zampini #else 486f6f667cfSStefano 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)); 48708122e43SStefano Zampini #endif 488d16cbb6bSStefano Zampini } else { 489d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 490d16cbb6bSStefano Zampini B_IL = 1; 491d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 492d16cbb6bSStefano 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)); 493d16cbb6bSStefano Zampini #else 494d16cbb6bSStefano 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)); 495d16cbb6bSStefano Zampini #endif 496d16cbb6bSStefano Zampini } 49708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 49808122e43SStefano Zampini if (B_ierr) { 49908122e43SStefano Zampini if (B_ierr < 0 ) { 50008122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 50108122e43SStefano Zampini } else if (B_ierr <= B_N) { 50208122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 50308122e43SStefano Zampini } else { 5049552c7c7SStefano 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); 50508122e43SStefano Zampini } 50608122e43SStefano Zampini } 50708122e43SStefano Zampini 50808122e43SStefano Zampini if (B_neigs > nmax) { 509fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 510fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 511fd14bc51SStefano Zampini } 512f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 51308122e43SStefano Zampini B_neigs = nmax; 51408122e43SStefano Zampini } 51508122e43SStefano Zampini 5169552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 5179552c7c7SStefano Zampini if (B_neigs < nmin_s) { 51808122e43SStefano Zampini PetscBLASInt B_neigs2; 51908122e43SStefano Zampini 520f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 521f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 522fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 523fd14bc51SStefano 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); 524fd14bc51SStefano Zampini } 5259ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 52608122e43SStefano Zampini PetscInt j; 52708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 52808122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 52908122e43SStefano Zampini } 53008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 53108122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 53208122e43SStefano Zampini } 53308122e43SStefano Zampini } else { 53408122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 53508122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 53608122e43SStefano Zampini } 53708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 53808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 539f6f667cfSStefano 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)); 54008122e43SStefano Zampini #else 541f6f667cfSStefano 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)); 54208122e43SStefano Zampini #endif 54308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 54408122e43SStefano Zampini B_neigs += B_neigs2; 54508122e43SStefano Zampini } 54608122e43SStefano Zampini if (B_ierr) { 54708122e43SStefano Zampini if (B_ierr < 0 ) { 54808122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 54908122e43SStefano Zampini } else if (B_ierr <= B_N) { 55008122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 55108122e43SStefano Zampini } else { 5529552c7c7SStefano 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); 55308122e43SStefano Zampini } 55408122e43SStefano Zampini } 555fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 556ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 55708122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 55808122e43SStefano Zampini if (eigs[j] == 0.0) { 559ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 56008122e43SStefano Zampini } else { 561ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 562fd14bc51SStefano Zampini } 56308122e43SStefano Zampini } 56408122e43SStefano Zampini } 56508122e43SStefano Zampini } else { 56608122e43SStefano Zampini /* TODO */ 56708122e43SStefano Zampini } 568aff50787SStefano Zampini } 5698bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 5708bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 5719162d606SStefano Zampini if (B_neigs) { 5729162d606SStefano 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); 573fd14bc51SStefano Zampini 574fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 5759552c7c7SStefano Zampini PetscInt ii; 5769552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 577ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 5789552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 579ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 580ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 581ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 582ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 583ac47001eSStefano Zampini #else 584ac47001eSStefano 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); 585ac47001eSStefano Zampini #endif 5869552c7c7SStefano Zampini } 5879552c7c7SStefano Zampini } 588fd14bc51SStefano Zampini } 58908122e43SStefano Zampini #if 0 5909162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 59108122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 59208122e43SStefano Zampini PetscScalar norm; 59308122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 5949162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 5959162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 59608122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 59708122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 59808122e43SStefano Zampini } else { 59908122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 60008122e43SStefano Zampini } 6019162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 602b1b3d7a2SStefano Zampini } 603b1b3d7a2SStefano Zampini #endif 6049162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 6059162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 6069162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 6079162d606SStefano Zampini cum++; 60808122e43SStefano Zampini } 60908122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 61008122e43SStefano Zampini /* shift for next computation */ 61108122e43SStefano Zampini cumarray += subset_size*subset_size; 61208122e43SStefano Zampini } 613fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 614fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 615fd14bc51SStefano Zampini } 61608122e43SStefano Zampini 61708122e43SStefano Zampini if (mss) { 61808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 61908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 620f6f667cfSStefano Zampini /* destroy matrices (junk) */ 621f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 622f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 62308122e43SStefano Zampini } 624f6f667cfSStefano Zampini if (allocated_S_St) { 625f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 626f6f667cfSStefano Zampini } 627f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 62808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 62908122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 63008122e43SStefano Zampini #endif 63108122e43SStefano Zampini if (pcbddc->dbg_flag) { 6321b968477SStefano Zampini PetscInt maxneigs_r; 63308122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 6349b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 63508122e43SStefano Zampini } 63608122e43SStefano Zampini PetscFunctionReturn(0); 63708122e43SStefano Zampini } 638b1b3d7a2SStefano Zampini 639674ae819SStefano Zampini #undef __FUNCT__ 640c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 641c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 642c8587f34SStefano Zampini { 643c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6448629588bSStefano Zampini PetscScalar *coarse_submat_vals; 645c8587f34SStefano Zampini PetscErrorCode ierr; 646c8587f34SStefano Zampini 647c8587f34SStefano Zampini PetscFunctionBegin; 648f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 6495e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 650c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 651c8587f34SStefano Zampini 652684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 6530fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 654684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 655c8587f34SStefano Zampini 656c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 657b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 658c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 659c8587f34SStefano Zampini } 660c8587f34SStefano Zampini 6618629588bSStefano Zampini /* 6628629588bSStefano Zampini Setup local correction and local part of coarse basis. 6638629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 6648629588bSStefano Zampini */ 66547f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 6668629588bSStefano Zampini 6678629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 6688629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 6698629588bSStefano Zampini 6708629588bSStefano Zampini /* free */ 6718629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 672c8587f34SStefano Zampini PetscFunctionReturn(0); 673c8587f34SStefano Zampini } 674c8587f34SStefano Zampini 675c8587f34SStefano Zampini #undef __FUNCT__ 676674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 677674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 678674ae819SStefano Zampini { 679674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 680674ae819SStefano Zampini PetscErrorCode ierr; 681674ae819SStefano Zampini 682674ae819SStefano Zampini PetscFunctionBegin; 683674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 684674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 685674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 686674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 687785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 688674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 689f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 690f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 691785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 69263602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 69363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 694674ae819SStefano Zampini PetscFunctionReturn(0); 695674ae819SStefano Zampini } 696674ae819SStefano Zampini 697674ae819SStefano Zampini #undef __FUNCT__ 698674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 699674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 700674ae819SStefano Zampini { 701674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 702674ae819SStefano Zampini PetscErrorCode ierr; 703674ae819SStefano Zampini 704674ae819SStefano Zampini PetscFunctionBegin; 705b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 706674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 707674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 708674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 709b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 710674ae819SStefano Zampini PetscFunctionReturn(0); 711674ae819SStefano Zampini } 712674ae819SStefano Zampini 713674ae819SStefano Zampini #undef __FUNCT__ 714674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 715674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 716674ae819SStefano Zampini { 717674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 71806656605SStefano Zampini PetscScalar *array; 719674ae819SStefano Zampini PetscErrorCode ierr; 720674ae819SStefano Zampini 721674ae819SStefano Zampini PetscFunctionBegin; 722674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 72358da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 72406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 72506656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 72658da7f69SStefano Zampini } 727674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 728674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 72915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 73015aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 731674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 732674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 733674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 73406656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 735674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 736674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 7378ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 738674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 739674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 740674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 741f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 742f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 743f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 744f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 745727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 7460e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 747f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 74870cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7496e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 75081d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 7510369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 7528b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 7538b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 75481d14e9dSStefano Zampini ierr = PetscFree2(pcbddc->B0_cols,pcbddc->B0_vals);CHKERRQ(ierr); 755674ae819SStefano Zampini PetscFunctionReturn(0); 756674ae819SStefano Zampini } 757674ae819SStefano Zampini 758674ae819SStefano Zampini #undef __FUNCT__ 759f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 760f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 7616bfb1811SStefano Zampini { 7626bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7636bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 7646bfb1811SStefano Zampini VecType impVecType; 765019a44ceSStefano Zampini PetscInt n_constraints,n_R,old_size,n_benign; 7666bfb1811SStefano Zampini PetscErrorCode ierr; 7676bfb1811SStefano Zampini 7686bfb1811SStefano Zampini PetscFunctionBegin; 769f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 770019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 771f4ddd8eeSStefano Zampini } 772e7b262bdSStefano Zampini /* get sizes */ 773c9ed8603SStefano Zampini n_benign = 0; 774c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) n_benign = 1; 775019a44ceSStefano Zampini n_constraints = pcbddc->local_primal_size - n_benign - pcbddc->n_vertices; 776b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 7776bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 778e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 779e7b262bdSStefano Zampini /* R nodes */ 780e7b262bdSStefano Zampini old_size = -1; 781e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 782e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 783e7b262bdSStefano Zampini } 784e7b262bdSStefano Zampini if (n_R != old_size) { 785e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 786e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 7876bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 7886bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 7896bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 7906bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 791e7b262bdSStefano Zampini } 792e7b262bdSStefano Zampini /* local primal dofs */ 793e7b262bdSStefano Zampini old_size = -1; 794e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 795e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 796e7b262bdSStefano Zampini } 797e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 798e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 79983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 800e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 8016bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 802e7b262bdSStefano Zampini } 803e7b262bdSStefano Zampini /* local explicit constraints */ 804e7b262bdSStefano Zampini old_size = -1; 805e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 806e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 807e7b262bdSStefano Zampini } 808e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 809e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 81083b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 81183b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 81283b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 81383b7ccabSStefano Zampini } 8146bfb1811SStefano Zampini PetscFunctionReturn(0); 8156bfb1811SStefano Zampini } 8166bfb1811SStefano Zampini 8176bfb1811SStefano Zampini #undef __FUNCT__ 81847f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 81947f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 82088ebb749SStefano Zampini { 82125084f0cSStefano Zampini PetscErrorCode ierr; 82225084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 82388ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 82488ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 825d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 82625084f0cSStefano Zampini /* submatrices of local problem */ 82780677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 828019a44ceSStefano Zampini /* submatrices of benign trick */ 829d16cbb6bSStefano Zampini Mat B0_V = NULL; 83006656605SStefano Zampini /* submatrices of local coarse problem */ 83106656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 83225084f0cSStefano Zampini /* working matrices */ 83306656605SStefano Zampini Mat C_CR; 83425084f0cSStefano Zampini /* additional working stuff */ 83506656605SStefano Zampini PC pc_R; 836d12edf2fSStefano Zampini Mat F,B0 = NULL; 83706656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 83806656605SStefano Zampini 83925084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 84006656605SStefano Zampini PetscScalar *work; 84106656605SStefano Zampini PetscInt *idx_V_B; 842d12edf2fSStefano Zampini PetscInt n,n_vertices,n_constraints,n_benign,p0_lidx_I = 0; 84306656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 844b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 84545a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 84688ebb749SStefano Zampini MatType impMatType; 84725084f0cSStefano Zampini /* some shortcuts to scalars */ 84806656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 84988ebb749SStefano Zampini 85088ebb749SStefano Zampini PetscFunctionBegin; 851c9ed8603SStefano Zampini n_benign = 0; 852c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) n_benign = 1; 853b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 854019a44ceSStefano Zampini n_constraints = pcbddc->local_primal_size - n_benign - n_vertices; 85588ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 856b371cd4fSStefano Zampini n_B = pcis->n_B; 857b371cd4fSStefano Zampini n_D = pcis->n - n_B; 85888ebb749SStefano Zampini n_R = pcis->n - n_vertices; 85988ebb749SStefano Zampini 86088ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 86188ebb749SStefano Zampini impMatType = MATSEQDENSE; 86288ebb749SStefano Zampini 86388ebb749SStefano Zampini /* vertices in boundary numbering */ 864785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 8650e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 86688ebb749SStefano Zampini if (i != n_vertices) { 86722d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 86888ebb749SStefano Zampini } 86988ebb749SStefano Zampini 87006656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 871019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 87206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 87306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 87406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 87506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 87606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 87706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 87806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 87906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 88006656605SStefano Zampini 88106656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 88206656605SStefano Zampini /* allocate workspace */ 88306656605SStefano Zampini n = 0; 88406656605SStefano Zampini if (n_constraints) { 88506656605SStefano Zampini n += n_R*n_constraints; 88606656605SStefano Zampini } 88706656605SStefano Zampini if (n_vertices) { 88806656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 88980677318SStefano Zampini n = PetscMax((n_R+n_B)*n_vertices,n); 89006656605SStefano Zampini } 8913301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 89206656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 89306656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 89406656605SStefano Zampini } 89506656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 89606656605SStefano Zampini 89706656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 89806656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 89906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 90006656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 90106656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 90206656605SStefano Zampini if (isLU || isILU || isCHOL) { 90306656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 904d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 905d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 906d62866d3SStefano Zampini MatFactorType type; 907d62866d3SStefano Zampini 9086816873aSStefano Zampini F = reuse_mumps->F; 9096816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 910d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 91106656605SStefano Zampini } else { 91206656605SStefano Zampini F = NULL; 91306656605SStefano Zampini } 91406656605SStefano Zampini 91588ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 91688ebb749SStefano Zampini if (n_constraints) { 91706656605SStefano Zampini Mat M1,M2,M3; 91880677318SStefano Zampini Mat auxmat; 91906656605SStefano Zampini IS is_aux; 92080677318SStefano Zampini PetscScalar *array,*array2; 92106656605SStefano Zampini 922f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 92380677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 92488ebb749SStefano Zampini 92525084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 92625084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 9278ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 92880677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 92988ebb749SStefano Zampini 93080677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 93180677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 93206656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 93388ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 93406656605SStefano Zampini const PetscScalar *row_cmat_values; 93506656605SStefano Zampini const PetscInt *row_cmat_indices; 93606656605SStefano Zampini PetscInt size_of_constraint,j; 93788ebb749SStefano Zampini 93806656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 93906656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 94006656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 94106656605SStefano Zampini } 94206656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 94306656605SStefano Zampini } 94480677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 94506656605SStefano Zampini if (F) { 94606656605SStefano Zampini Mat B; 94706656605SStefano Zampini 94806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 94980677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 95006656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 95106656605SStefano Zampini } else { 95280677318SStefano Zampini PetscScalar *marr; 95380677318SStefano Zampini 95480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 95506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 95606656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 95780677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*n_R);CHKERRQ(ierr); 95806656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 95906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 96006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 96106656605SStefano Zampini } 96280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 96306656605SStefano Zampini } 96480677318SStefano Zampini if (!pcbddc->switch_static) { 96580677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 96680677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 96780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 96880677318SStefano Zampini for (i=0;i<n_constraints;i++) { 96980677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*n_R);CHKERRQ(ierr); 97080677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 97180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 97280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 97380677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 97480677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 97580677318SStefano Zampini } 97680677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 97780677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 97880677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 97980677318SStefano Zampini } else { 98080677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 98180677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 98225084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 98380677318SStefano Zampini } 98480677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 98580677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 98680677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 98706656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 98806656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 98980677318SStefano Zampini if (isCHOL) { 99080677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 99180677318SStefano Zampini } else { 99225084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 99380677318SStefano Zampini } 99480677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 99506656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 99625084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 99725084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 99825084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 99980677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 100080677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 100180677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 100206656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 100306656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1004f4ddd8eeSStefano Zampini } 100588ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 1006d16cbb6bSStefano Zampini if (n_benign) { 1007d16cbb6bSStefano Zampini IS dummy; 1008d16cbb6bSStefano Zampini Mat B0_R; 1009d16cbb6bSStefano Zampini PetscReal norm; 1010d16cbb6bSStefano Zampini PetscInt ii[2]; 1011d16cbb6bSStefano Zampini 1012d16cbb6bSStefano Zampini ii[0] = 0; 1013d16cbb6bSStefano Zampini ii[1] = pcbddc->B0_ncol; 1014d16cbb6bSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,1,pcis->n,ii,pcbddc->B0_cols,pcbddc->B0_vals,&B0);CHKERRQ(ierr); 1015d16cbb6bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&dummy);CHKERRQ(ierr); 1016d16cbb6bSStefano Zampini ierr = MatGetSubMatrix(B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1017d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1018d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1019d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1020d16cbb6bSStefano Zampini } 1021d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1022d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1023d16cbb6bSStefano Zampini } 1024d16cbb6bSStefano Zampini 102588ebb749SStefano Zampini if (n_vertices) { 102606656605SStefano Zampini IS is_aux; 10273a50541eSStefano Zampini 10286816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 10296816873aSStefano Zampini IS tis; 10306816873aSStefano Zampini 10316816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 10326816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 10336816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 10346816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 10356816873aSStefano Zampini } else { 10363a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 10376816873aSStefano Zampini } 10389577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 10399577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 104004708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 1041019a44ceSStefano Zampini if (n_benign) { 1042019a44ceSStefano Zampini IS dummy; 1043019a44ceSStefano Zampini 1044019a44ceSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&dummy);CHKERRQ(ierr); 1045019a44ceSStefano Zampini ierr = MatGetSubMatrix(B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1046019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1047019a44ceSStefano Zampini } 104825084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 104988ebb749SStefano Zampini } 105088ebb749SStefano Zampini 105188ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1052f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 105306656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 105406656605SStefano Zampini if (pcbddc->coarse_phi_D) { 105506656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 105606656605SStefano Zampini } 1057f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 105806656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 105906656605SStefano Zampini PetscScalar *marray; 106006656605SStefano Zampini 106106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 106206656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1063f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1064f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1065f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1066f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1067f4ddd8eeSStefano Zampini } 1068f4ddd8eeSStefano Zampini } 106906656605SStefano Zampini 1070f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 107106656605SStefano Zampini PetscScalar *marray; 107288ebb749SStefano Zampini 107306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 10748eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 107506656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 107688ebb749SStefano Zampini } 10773301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 107806656605SStefano Zampini n *= 2; 107988ebb749SStefano Zampini } 108006656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 108106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 108206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 10838eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 108406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 108506656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 108688ebb749SStefano Zampini } 10873301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 108806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 10898eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 109006656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 109106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 109288ebb749SStefano Zampini } 109388ebb749SStefano Zampini } else { 1094c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1095c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 10961b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1097c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1098c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1099c0553b1fSStefano Zampini } 110088ebb749SStefano Zampini } 110106656605SStefano Zampini } 1102019a44ceSStefano Zampini 110306656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 1104d12edf2fSStefano Zampini if (n_benign && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1105d12edf2fSStefano Zampini const PetscInt *idxs; 1106d12edf2fSStefano Zampini 1107d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1108d12edf2fSStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx,pcis->n-pcis->n_B,idxs,&p0_lidx_I);CHKERRQ(ierr); 1109d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1110d12edf2fSStefano Zampini } 1111d16cbb6bSStefano Zampini 111206656605SStefano Zampini /* vertices */ 111306656605SStefano Zampini if (n_vertices) { 111416f15bc4SStefano Zampini 111504708bb6SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 111604708bb6SStefano Zampini 111716f15bc4SStefano Zampini if (n_R) { 111806656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 111906656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 112016f15bc4SStefano Zampini PetscScalar *x,*y; 112104708bb6SStefano Zampini PetscBool isseqaij; 112206656605SStefano Zampini 112321eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 112406656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 112504708bb6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 11266816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 112706656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 112806656605SStefano Zampini } else { 112906656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 113006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 113106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 113206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 113306656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 113406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 113506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 113606656605SStefano Zampini } 113706656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 113806656605SStefano Zampini } 113980677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 114006656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 114106656605SStefano Zampini if (n_constraints) { 114206656605SStefano Zampini Mat B; 114380677318SStefano Zampini 1144b3d85658SStefano Zampini ierr = PetscMemzero(work+n_R*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 114580677318SStefano Zampini for (i=0;i<n_vertices;i++) { 114680677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 114780677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+n_R*n_vertices+i*n_B);CHKERRQ(ierr); 114880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 114980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 115080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 115180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 115280677318SStefano Zampini } 115380677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 115480677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 115580677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 115606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 115780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 115806656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 115906656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 116006656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 116106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 116206656605SStefano Zampini } 116304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 116404708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 116504708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 116604708bb6SStefano Zampini } 116706656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 116880677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 116906656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 117006656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 117106656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 117206656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 117306656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 117406656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 117506656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1176d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1177019a44ceSStefano Zampini } else { 1178d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1179d16cbb6bSStefano Zampini } 1180d16cbb6bSStefano Zampini if (n_benign) { 1181019a44ceSStefano Zampini const PetscScalar *vals; 1182019a44ceSStefano Zampini const PetscInt *idxs; 1183019a44ceSStefano Zampini PetscInt n,j; 1184019a44ceSStefano Zampini 1185019a44ceSStefano Zampini ierr = MatGetRow(B0_V,0,&n,&idxs,&vals);CHKERRQ(ierr); 1186d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 1187d16cbb6bSStefano Zampini coarse_submat_vals[(pcbddc->local_primal_size-1)*pcbddc->local_primal_size+idxs[j]] = vals[j]; 1188d16cbb6bSStefano Zampini coarse_submat_vals[(idxs[j]+1)*pcbddc->local_primal_size-1] = vals[j]; 1189019a44ceSStefano Zampini } 1190019a44ceSStefano Zampini ierr = MatRestoreRow(B0_V,0,&n,&idxs,&vals);CHKERRQ(ierr); 119116f15bc4SStefano Zampini } 119221eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1193d16cbb6bSStefano Zampini 119406656605SStefano Zampini /* coarse basis functions */ 119506656605SStefano Zampini for (i=0;i<n_vertices;i++) { 119616f15bc4SStefano Zampini PetscScalar *y; 119716f15bc4SStefano Zampini 119806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 119906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 120006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 120106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 120206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 120306656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 120406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 120506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 120606656605SStefano Zampini 120706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 120806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 120906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 121006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 121106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 121206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 1213a0aff763SStefano Zampini if (n_benign) y[n_D*i+p0_lidx_I] = 0.0; 121406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 121506656605SStefano Zampini } 121606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 121706656605SStefano Zampini } 121804708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 121904708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 122006656605SStefano Zampini } 122106656605SStefano Zampini 122206656605SStefano Zampini if (n_constraints) { 122306656605SStefano Zampini Mat B; 122406656605SStefano Zampini 122506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 122606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 122780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 122806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 122906656605SStefano Zampini if (n_vertices) { 123080677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 123180677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 123280677318SStefano Zampini } else { 123380677318SStefano Zampini Mat S_VCt; 123480677318SStefano Zampini 123580677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 123680677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 123780677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 123880677318SStefano Zampini } 123906656605SStefano Zampini } 124006656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 124106656605SStefano Zampini /* coarse basis functions */ 124206656605SStefano Zampini for (i=0;i<n_constraints;i++) { 124306656605SStefano Zampini PetscScalar *y; 124406656605SStefano Zampini 124506656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 124606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 124706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 124806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 124906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 125006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 125106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 125206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 125306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 125406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 125506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 125606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 125706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 1258d16cbb6bSStefano Zampini if (n_benign) y[n_D*(i+n_vertices)+p0_lidx_I] = 0.0; 125906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 126006656605SStefano Zampini } 126106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 126206656605SStefano Zampini } 126306656605SStefano Zampini } 126480677318SStefano Zampini if (n_constraints) { 126580677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 126680677318SStefano Zampini } 126706656605SStefano Zampini 1268019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1269019a44ceSStefano Zampini 127006656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 12713301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 127206656605SStefano Zampini 127306656605SStefano Zampini if (n_constraints) { 127416f15bc4SStefano Zampini Mat S_CCT,B_C; 127506656605SStefano Zampini 127680677318SStefano Zampini /* this is a lazy thing */ 127780677318SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 127806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 127906656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 128006656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 128116f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 128206656605SStefano Zampini if (n_vertices) { 128316f15bc4SStefano Zampini Mat B_V,S_VCT; 128406656605SStefano Zampini 128506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 128606656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 128706656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 128806656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 128916f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 129006656605SStefano Zampini } 129106656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 129280677318SStefano Zampini } else { /* if there are no constraints, reset work */ 129380677318SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 129406656605SStefano Zampini } 129516f15bc4SStefano Zampini if (n_vertices && n_R) { 129606656605SStefano Zampini Mat A_VRT; 129780677318SStefano Zampini PetscScalar *marray; 129806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 129906656605SStefano Zampini 130080677318SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_VRT);CHKERRQ(ierr); 130180677318SStefano Zampini ierr = MatConvert(A_VRT,impMatType,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 130280677318SStefano Zampini ierr = MatDenseGetArray(A_VRT,&marray);CHKERRQ(ierr); 130306656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 130480677318SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,marray,&B_one,work,&B_one)); 130580677318SStefano Zampini ierr = MatDenseRestoreArray(A_VRT,&marray);CHKERRQ(ierr); 130616f15bc4SStefano Zampini ierr = MatDestroy(&A_VRT);CHKERRQ(ierr); 130706656605SStefano Zampini } 130806656605SStefano Zampini 130906656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 131006656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 131106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 131206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 131306656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 131406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 131506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 131606656605SStefano Zampini } 131706656605SStefano Zampini } else { 131806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 131906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 132006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 132106656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 132206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 132306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 132406656605SStefano Zampini } 132506656605SStefano Zampini } 132606656605SStefano Zampini /* coarse basis functions */ 132706656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 132806656605SStefano Zampini PetscScalar *y; 132906656605SStefano Zampini 133006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 133106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 133206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 133306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 133406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 133506656605SStefano Zampini if (i<n_vertices) { 133606656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 133706656605SStefano Zampini } 133806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 133906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 134006656605SStefano Zampini 134106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 134206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 134306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 134406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 134506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 134606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 134706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 134806656605SStefano Zampini } 134906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 135006656605SStefano Zampini } 135106656605SStefano Zampini } 1352d62866d3SStefano Zampini /* free memory */ 135388ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 135406656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 135506656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 135606656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 135706656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 1358d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1359d62866d3SStefano Zampini if (n_vertices) { 1360d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1361d62866d3SStefano Zampini } 1362d62866d3SStefano Zampini if (n_constraints) { 1363d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 1364d62866d3SStefano Zampini } 136588ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 136688ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 136788ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1368d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 136988ebb749SStefano Zampini Mat coarse_sub_mat; 137025084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 137188ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 137288ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 137388ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 13748bec7fa6SStefano Zampini Mat C_B,CPHI; 13758bec7fa6SStefano Zampini IS is_dummy; 13768bec7fa6SStefano Zampini Vec mones; 137788ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 137888ebb749SStefano Zampini PetscReal real_value; 137988ebb749SStefano Zampini 138088ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 138188ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 138288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 138388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 138488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 138588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1386c0553b1fSStefano Zampini if (unsymmetric_check) { 138788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 138888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 138988ebb749SStefano Zampini } 139088ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 139188ebb749SStefano Zampini 139225084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 13933301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 139425084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1395c0553b1fSStefano Zampini if (unsymmetric_check) { 139688ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 139788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 139888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 139988ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 140088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 140188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 140288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 140388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 140488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 140588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 140688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 140788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 140888ebb749SStefano Zampini } else { 140988ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 141088ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 141188ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 141288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 141388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 141488ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 141588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 141688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 141788ebb749SStefano Zampini } 141888ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 141988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 142088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 142188ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 1422d12edf2fSStefano Zampini if (n_benign) { 1423d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 1424d12edf2fSStefano Zampini PetscScalar *data,*data2; 1425d12edf2fSStefano Zampini 1426d12edf2fSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&is_dummy);CHKERRQ(ierr); 1427d12edf2fSStefano Zampini ierr = MatGetSubMatrix(B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 1428d12edf2fSStefano Zampini ierr = MatGetSubMatrix(B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 1429d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 1430d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 1431d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 1432d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 1433d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1434d16cbb6bSStefano Zampini data[(pcbddc->local_primal_size-1)*pcbddc->local_primal_size+i] += data2[i]; 1435d16cbb6bSStefano Zampini data[(i+1)*pcbddc->local_primal_size-1] += data2[i]; 1436d12edf2fSStefano Zampini } 1437d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 1438d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 1439d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 1440d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 1441d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 1442d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 1443d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 1444d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1445d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 1446d12edf2fSStefano Zampini } 1447d12edf2fSStefano Zampini #if 0 1448d12edf2fSStefano Zampini { 1449d12edf2fSStefano Zampini PetscViewer viewer; 1450d12edf2fSStefano Zampini char filename[256]; 1451d12edf2fSStefano Zampini sprintf(filename,"proj_local_coarse_mat%d.m",PetscGlobalRank); 1452d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1453d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1454d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 1455d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1456d12edf2fSStefano Zampini } 1457d12edf2fSStefano Zampini #endif 145881d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 14598bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 14600fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 146106656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 14628bec7fa6SStefano Zampini 14638bec7fa6SStefano Zampini /* check constraints */ 1464d12edf2fSStefano Zampini if (!n_benign) { 14658bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 14668bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 14678bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 14688bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 14698bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 14708bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 14718bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1472bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 1473c0553b1fSStefano Zampini if (unsymmetric_check) { 1474bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 1475bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 1476bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 1477bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1478bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 147988ebb749SStefano Zampini } 14808bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 14818bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 14828bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 14838bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 1484d12edf2fSStefano Zampini } 148525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 148688ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 148788ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 148888ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 148988ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 149088ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 149188ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 149288ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 149388ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 149488ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 149588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 1496c0553b1fSStefano Zampini if (unsymmetric_check) { 149788ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 149888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 149988ebb749SStefano Zampini } 150088ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 150188ebb749SStefano Zampini } 1502d12edf2fSStefano Zampini ierr = MatDestroy(&B0);CHKERRQ(ierr); 15038629588bSStefano Zampini /* get back data */ 15048629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 150588ebb749SStefano Zampini PetscFunctionReturn(0); 150688ebb749SStefano Zampini } 150788ebb749SStefano Zampini 150888ebb749SStefano Zampini #undef __FUNCT__ 1509d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1510d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 1511aa0d41d4SStefano Zampini { 1512d65f70fdSStefano Zampini Mat *work_mat; 1513d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1514d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1515d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1516aa0d41d4SStefano Zampini PetscErrorCode ierr; 1517aa0d41d4SStefano Zampini 1518aa0d41d4SStefano Zampini PetscFunctionBegin; 1519d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1520d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1521d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1522d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1523aa0d41d4SStefano Zampini 1524d65f70fdSStefano Zampini if (!rsorted) { 1525906d46d4SStefano Zampini const PetscInt *idxs; 1526906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 1527aa0d41d4SStefano Zampini 1528d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1529d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1530d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1531d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1532aa0d41d4SStefano Zampini } 1533d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1534d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1535d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1536d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1537aa0d41d4SStefano Zampini } 1538d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1539d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1540d65f70fdSStefano Zampini } else { 1541d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1542d65f70fdSStefano Zampini isrow_s = isrow; 1543aa0d41d4SStefano Zampini } 1544906d46d4SStefano Zampini 1545d65f70fdSStefano Zampini if (!csorted) { 1546d65f70fdSStefano Zampini if (isrow == iscol) { 1547d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1548d65f70fdSStefano Zampini iscol_s = isrow_s; 1549d65f70fdSStefano Zampini } else { 1550d65f70fdSStefano Zampini const PetscInt *idxs; 1551d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1552906d46d4SStefano Zampini 1553d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1554d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1555d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1556d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1557d65f70fdSStefano Zampini } 1558d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1559d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1560d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1561d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1562d65f70fdSStefano Zampini } 1563d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1564d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1565d65f70fdSStefano Zampini } 1566d65f70fdSStefano Zampini } else { 1567d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1568d65f70fdSStefano Zampini iscol_s = iscol; 1569d65f70fdSStefano Zampini } 1570d65f70fdSStefano Zampini 1571d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1572d65f70fdSStefano Zampini 1573d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1574906d46d4SStefano Zampini Mat new_mat; 1575d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1576906d46d4SStefano Zampini 1577d65f70fdSStefano Zampini if (!rsorted) { 1578d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1579d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1580d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1581d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1582906d46d4SStefano Zampini } 1583d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1584d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1585d65f70fdSStefano Zampini } else { 1586d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1587906d46d4SStefano Zampini } 1588d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1589d65f70fdSStefano Zampini 1590d65f70fdSStefano Zampini if (!csorted) { 1591d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1592d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1593d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1594d65f70fdSStefano Zampini } else { 1595d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1596d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1597d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1598d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1599d65f70fdSStefano Zampini } 1600d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1601d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1602d65f70fdSStefano Zampini } 1603d65f70fdSStefano Zampini } else { 1604d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1605d65f70fdSStefano Zampini } 1606d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1607d65f70fdSStefano Zampini 1608d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1609d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1610d65f70fdSStefano Zampini work_mat[0] = new_mat; 1611d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1612d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1613d65f70fdSStefano Zampini } 1614d65f70fdSStefano Zampini 1615d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1616d65f70fdSStefano Zampini *B = work_mat[0]; 1617d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1618d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1619d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1620d65f70fdSStefano Zampini PetscFunctionReturn(0); 1621d65f70fdSStefano Zampini } 1622d65f70fdSStefano Zampini 1623d65f70fdSStefano Zampini #undef __FUNCT__ 16245e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 16255e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1626aa0d41d4SStefano Zampini { 1627aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 16285e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1629d65f70fdSStefano Zampini Mat new_mat; 16305e8657edSStefano Zampini IS is_local,is_global; 1631d65f70fdSStefano Zampini PetscInt local_size; 1632d65f70fdSStefano Zampini PetscBool isseqaij; 1633aa0d41d4SStefano Zampini PetscErrorCode ierr; 1634aa0d41d4SStefano Zampini 1635aa0d41d4SStefano Zampini PetscFunctionBegin; 1636aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16375e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 16385e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1639b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 1640aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1641d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 1642aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1643906d46d4SStefano Zampini 1644906d46d4SStefano Zampini /* check */ 1645906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1646906d46d4SStefano Zampini Vec x,x_change; 1647906d46d4SStefano Zampini PetscReal error; 1648906d46d4SStefano Zampini 16495e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1650906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 16515e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 1652e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1653e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1654d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 1655e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1656e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1657906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1658906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1659906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1660906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1661906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1662906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1663906d46d4SStefano Zampini } 1664906d46d4SStefano Zampini 166522d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 16669b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 166722d5777bSStefano Zampini if (isseqaij) { 1668d65f70fdSStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1669aa0d41d4SStefano Zampini } else { 1670aa0d41d4SStefano Zampini Mat work_mat; 1671aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1672d65f70fdSStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1673aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1674aa0d41d4SStefano Zampini } 16753301b35fSStefano Zampini if (matis->A->symmetric_set) { 16763301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 1677e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 16783301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 1679e496cd5dSStefano Zampini #endif 16803301b35fSStefano Zampini } 168145a1bb75SStefano Zampini /* 168245a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1683d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 168445a1bb75SStefano Zampini */ 1685d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1686aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1687aa0d41d4SStefano Zampini } 1688aa0d41d4SStefano Zampini 1689aa0d41d4SStefano Zampini #undef __FUNCT__ 1690a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 16918ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 1692a64d13efSStefano Zampini { 1693a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1694a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1695d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 169653892102SStefano Zampini PetscInt *idx_R_local=NULL; 16973a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 16983a50541eSStefano Zampini PetscInt vbs,bs; 16996816873aSStefano Zampini PetscBT bitmask=NULL; 1700a64d13efSStefano Zampini PetscErrorCode ierr; 1701a64d13efSStefano Zampini 1702a64d13efSStefano Zampini PetscFunctionBegin; 1703b23d619eSStefano Zampini /* 1704b23d619eSStefano Zampini No need to setup local scatters if 1705b23d619eSStefano Zampini - primal space is unchanged 1706b23d619eSStefano Zampini AND 1707b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 1708b23d619eSStefano Zampini AND 1709b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 1710b23d619eSStefano Zampini */ 1711b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 1712f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 1713f4ddd8eeSStefano Zampini } 1714f4ddd8eeSStefano Zampini /* destroy old objects */ 1715f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1716f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1717f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1718a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 1719b371cd4fSStefano Zampini n_B = pcis->n_B; 1720b371cd4fSStefano Zampini n_D = pcis->n - n_B; 1721b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 17223a50541eSStefano Zampini 1723a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 17246816873aSStefano Zampini 172553892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 17266816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 1727854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 1728a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 1729a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 17300e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 1731a64d13efSStefano Zampini } 1732a64d13efSStefano Zampini 1733a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 17344641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 17356816873aSStefano Zampini idx_R_local[n_R++] = i; 1736a64d13efSStefano Zampini } 1737a64d13efSStefano Zampini } 173853892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 17396816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 17406816873aSStefano Zampini 174153892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 174253892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 17436816873aSStefano Zampini } 17443a50541eSStefano Zampini 17453a50541eSStefano Zampini /* Block code */ 17463a50541eSStefano Zampini vbs = 1; 17473a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 17483a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 17493a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 17503a50541eSStefano Zampini PetscInt *vary; 1751d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 1752785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 17533a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 1754d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 1755d3df7717SStefano 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 */ 17560e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 1757d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 17583a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 17593a50541eSStefano Zampini is_blocked = PETSC_FALSE; 17603a50541eSStefano Zampini break; 17613a50541eSStefano Zampini } 17623a50541eSStefano Zampini } 1763d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 1764d3df7717SStefano Zampini } else { 1765d3df7717SStefano Zampini /* Verify directly the R set */ 1766d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 1767d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 1768d3df7717SStefano Zampini for (j=1; j<bs; j++) { 1769d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 1770d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 1771d3df7717SStefano Zampini break; 1772d3df7717SStefano Zampini } 1773d3df7717SStefano Zampini } 1774d3df7717SStefano Zampini } 1775d3df7717SStefano Zampini } 17763a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 17773a50541eSStefano Zampini vbs = bs; 17783a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 17793a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 17803a50541eSStefano Zampini } 17813a50541eSStefano Zampini } 17823a50541eSStefano Zampini } 17833a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 178453892102SStefano Zampini if (sub_schurs->reuse_mumps) { 178553892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 178653892102SStefano Zampini 178753892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 178853892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 178953892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 179053892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 179153892102SStefano Zampini } else { 17923a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 179353892102SStefano Zampini } 1794a64d13efSStefano Zampini 1795a64d13efSStefano Zampini /* print some info if requested */ 1796a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 1797c9ed8603SStefano Zampini PetscInt benign = 0; 1798019a44ceSStefano Zampini 1799c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) benign = 1; 1800a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1801a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 18020fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1803a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 1804a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 1805019a44ceSStefano 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); 1806a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1807a64d13efSStefano Zampini } 1808a64d13efSStefano Zampini 1809a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 18106816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 18116816873aSStefano Zampini IS is_aux1,is_aux2; 18126816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 18136816873aSStefano Zampini 18143a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1815854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 1816854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 1817a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 18184641a718SStefano Zampini for (i=0; i<n_D; i++) { 18194641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 18204641a718SStefano Zampini } 1821a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1822a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 18234641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 18244641a718SStefano Zampini aux_array1[j++] = i; 1825a64d13efSStefano Zampini } 1826a64d13efSStefano Zampini } 1827a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1828a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1829a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 18304641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 18314641a718SStefano Zampini aux_array2[j++] = i; 1832a64d13efSStefano Zampini } 1833a64d13efSStefano Zampini } 1834a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1835a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 1836a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 1837a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1838a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 1839a64d13efSStefano Zampini 18408eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1841785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 1842a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 18434641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 18444641a718SStefano Zampini aux_array1[j++] = i; 1845a64d13efSStefano Zampini } 1846a64d13efSStefano Zampini } 1847a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1848a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 1849a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1850a64d13efSStefano Zampini } 18514641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 18523a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1853d62866d3SStefano Zampini } else { 185453892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 18556816873aSStefano Zampini IS tis; 18566816873aSStefano Zampini PetscInt schur_size; 18576816873aSStefano Zampini 185853892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 18596816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 186053892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 18616816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 18626816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 18636816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 18646816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 18656816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 1866d62866d3SStefano Zampini } 1867d62866d3SStefano Zampini } 1868a64d13efSStefano Zampini PetscFunctionReturn(0); 1869a64d13efSStefano Zampini } 1870a64d13efSStefano Zampini 1871304d26faSStefano Zampini 1872304d26faSStefano Zampini #undef __FUNCT__ 1873304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 1874684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 1875304d26faSStefano Zampini { 1876304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1877304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1878304d26faSStefano Zampini PC pc_temp; 1879304d26faSStefano Zampini Mat A_RR; 1880f4ddd8eeSStefano Zampini MatReuse reuse; 1881304d26faSStefano Zampini PetscScalar m_one = -1.0; 1882304d26faSStefano Zampini PetscReal value; 188304708bb6SStefano Zampini PetscInt n_D,n_R; 18849577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 1885304d26faSStefano Zampini PetscErrorCode ierr; 1886e604994aSStefano Zampini /* prefixes stuff */ 1887312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 1888e604994aSStefano Zampini size_t len; 1889304d26faSStefano Zampini 1890304d26faSStefano Zampini PetscFunctionBegin; 1891304d26faSStefano Zampini 1892e604994aSStefano Zampini /* compute prefixes */ 1893e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 1894e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 1895e604994aSStefano Zampini if (!pcbddc->current_level) { 1896e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1897e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1898e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1899e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1900e604994aSStefano Zampini } else { 1901e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 1902312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 1903e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 1904e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 1905312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 1906312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 190734d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 190834d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 1909e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1910e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1911e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 1912e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 1913e604994aSStefano Zampini } 1914e604994aSStefano Zampini 1915304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 1916684f6988SStefano Zampini if (dirichlet) { 1917d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 19183301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 19193301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 1920964fefecSStefano Zampini } 1921ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 1922964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 1923304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 1924304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 1925304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 1926304d26faSStefano Zampini /* default */ 1927304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1928e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 19299577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1930304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 19319577ea80SStefano Zampini if (issbaij) { 19329577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 19339577ea80SStefano Zampini } else { 1934304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 19359577ea80SStefano Zampini } 1936304d26faSStefano Zampini /* Allow user's customization */ 1937304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1938304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1939304d26faSStefano Zampini } 1940d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 1941d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 1942d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1943d62866d3SStefano Zampini 1944d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 1945d5574798SStefano Zampini } 1946304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1947304d26faSStefano Zampini if (!n_D) { 1948304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 1949304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1950304d26faSStefano Zampini } 1951304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 1952304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1953304d26faSStefano Zampini /* set ksp_D into pcis data */ 1954304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 1955304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 1956304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 1957684f6988SStefano Zampini } 1958304d26faSStefano Zampini 1959304d26faSStefano Zampini /* NEUMANN PROBLEM */ 1960684f6988SStefano Zampini A_RR = 0; 1961684f6988SStefano Zampini if (neumann) { 1962d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 196304708bb6SStefano Zampini PetscInt ibs,mbs; 196404708bb6SStefano Zampini PetscBool issbaij; 196504708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1966f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 19678ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 1968f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 1969f4ddd8eeSStefano Zampini PetscInt nn_R; 197081d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 1971f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1972f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 1973f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 1974f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 1975f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1976f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1977f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 1978727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 1979f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1980f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1981f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 1982f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 1983f4ddd8eeSStefano Zampini } 1984f4ddd8eeSStefano Zampini } 1985f4ddd8eeSStefano Zampini /* last check */ 1986d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 1987f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1988f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1989f4ddd8eeSStefano Zampini } 1990f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 1991f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1992f4ddd8eeSStefano Zampini } 1993f4ddd8eeSStefano Zampini /* extract A_RR */ 1994af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 1995af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 199604708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 199704708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 199804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 199904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 200004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2001af732b37SStefano Zampini } else { 200204708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 20036816873aSStefano Zampini } 200404708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 200504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 200604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 200704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 200804708bb6SStefano Zampini } else { 200904708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 201004708bb6SStefano Zampini } 201104708bb6SStefano Zampini } 201204708bb6SStefano Zampini if (!sub_schurs->reuse_mumps) { 2013f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 20143301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 20153301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 20166816873aSStefano Zampini } 20176816873aSStefano Zampini } else { 20186816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 20196816873aSStefano Zampini 20206816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 20216816873aSStefano Zampini ierr = PCGetOperators(reuse_mumps->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 20226816873aSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2023af732b37SStefano Zampini } 2024f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2025304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2026304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2027304d26faSStefano Zampini /* default */ 2028304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2029e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2030304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 20319577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 20329577ea80SStefano Zampini if (issbaij) { 20339577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 20349577ea80SStefano Zampini } else { 2035304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 20369577ea80SStefano Zampini } 2037304d26faSStefano Zampini /* Allow user's customization */ 2038304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2039304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2040304d26faSStefano Zampini } 2041d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2042304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2043304d26faSStefano Zampini if (!n_R) { 2044304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2045304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2046304d26faSStefano Zampini } 2047d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 2048d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2049d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2050d62866d3SStefano Zampini 2051d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 2052d62866d3SStefano Zampini } 2053304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2054304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2055684f6988SStefano Zampini } 20566816873aSStefano Zampini /* free Neumann problem's matrix */ 20576816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2058304d26faSStefano Zampini 2059304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 20600fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2061684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2062684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2063684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2064684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2065684f6988SStefano Zampini } 2066684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 20670fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 20680fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 20690fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 20700fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 20710fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2072304d26faSStefano Zampini /* need to be adapted? */ 2073b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2074b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2075b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2076304d26faSStefano Zampini /* print info */ 2077304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2078e604994aSStefano 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); 2079304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2080304d26faSStefano Zampini } 2081b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2082298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2083304d26faSStefano Zampini } 2084684f6988SStefano Zampini } 2085684f6988SStefano Zampini if (neumann) { /* Neumann */ 20866816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 20870fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 20880fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 20890fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 20900fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 20910fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2092304d26faSStefano Zampini /* need to be adapted? */ 2093b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2094b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2095304d26faSStefano Zampini /* print info */ 2096304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2097e604994aSStefano 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); 2098304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2099304d26faSStefano Zampini } 2100b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2101298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2102304d26faSStefano Zampini } 21030fccc4e9SStefano Zampini } 2104684f6988SStefano Zampini } 2105304d26faSStefano Zampini PetscFunctionReturn(0); 2106304d26faSStefano Zampini } 2107304d26faSStefano Zampini 2108304d26faSStefano Zampini #undef __FUNCT__ 2109ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 211080677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2111674ae819SStefano Zampini { 2112674ae819SStefano Zampini PetscErrorCode ierr; 2113674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2114be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2115674ae819SStefano Zampini 2116674ae819SStefano Zampini PetscFunctionBegin; 2117be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 211880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 211920c7b377SStefano Zampini } 212080677318SStefano Zampini if (!pcbddc->switch_static) { 212180677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 212280677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 212380677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 212420c7b377SStefano Zampini } 2125be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 212680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212820c7b377SStefano Zampini } else { 2129be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2130be83ff47SStefano Zampini 213153892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213253892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213320c7b377SStefano Zampini } 2134be83ff47SStefano Zampini } else { 213580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 214080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 214180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 214280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2144674ae819SStefano Zampini } 2145674ae819SStefano Zampini } 2146be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 214780677318SStefano Zampini if (applytranspose) { 214880677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 214980677318SStefano Zampini } else { 215080677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 215180677318SStefano Zampini } 215253892102SStefano Zampini #if defined(PETSC_HAVE_MUMPS) 2153be83ff47SStefano Zampini } else { 2154be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2155be83ff47SStefano Zampini 2156be83ff47SStefano Zampini if (applytranspose) { 215753892102SStefano Zampini ierr = MatMumpsSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2158be83ff47SStefano Zampini } else { 215953892102SStefano Zampini ierr = MatMumpsSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2160be83ff47SStefano Zampini } 216153892102SStefano Zampini #endif 2162be83ff47SStefano Zampini } 216380677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 216480677318SStefano Zampini if (!pcbddc->switch_static) { 2165be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 216680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 216780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2168be83ff47SStefano Zampini } else { 2169be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2170be83ff47SStefano Zampini 217153892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217253892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2173be83ff47SStefano Zampini } 217480677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 217580677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 217680677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 217780677318SStefano Zampini } 217880677318SStefano Zampini } else { 217980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218380677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 218480677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 218580677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 218680677318SStefano Zampini } 218780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 219080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2191674ae819SStefano Zampini } 2192674ae819SStefano Zampini PetscFunctionReturn(0); 2193674ae819SStefano Zampini } 2194674ae819SStefano Zampini 2195dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2196674ae819SStefano Zampini #undef __FUNCT__ 2197674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2198dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2199674ae819SStefano Zampini { 2200674ae819SStefano Zampini PetscErrorCode ierr; 2201674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2202674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2203674ae819SStefano Zampini const PetscScalar zero = 0.0; 2204674ae819SStefano Zampini 2205674ae819SStefano Zampini PetscFunctionBegin; 2206dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2207dc359a40SStefano Zampini if (applytranspose) { 2208674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 22098eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2210dc359a40SStefano Zampini } else { 2211674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2212674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 221315aaf578SStefano Zampini } 2214efc2fbd9SStefano Zampini 2215efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 2216c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 2217efc2fbd9SStefano Zampini PetscScalar *array; 2218efc2fbd9SStefano Zampini 2219efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2220efc2fbd9SStefano Zampini array[pcbddc->local_primal_size-1] += pcbddc->benign_p0; 2221efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2222efc2fbd9SStefano Zampini } 2223efc2fbd9SStefano Zampini 222412edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 222512edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 222612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 222712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 222812edc857SStefano Zampini 22299f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 223012edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 223112edc857SStefano Zampini if (pcbddc->coarse_ksp) { 2232964fefecSStefano Zampini Vec rhs,sol; 2233964fefecSStefano Zampini 2234964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2235964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 223612edc857SStefano Zampini if (applytranspose) { 2237964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 223812edc857SStefano Zampini } else { 2239964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 224012edc857SStefano Zampini } 224112edc857SStefano Zampini } 2242674ae819SStefano Zampini 2243674ae819SStefano Zampini /* Local solution on R nodes */ 224480677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 224580677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 22469f00e9b4SStefano Zampini } 2247674ae819SStefano Zampini 22489f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 22499f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 225012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2251674ae819SStefano Zampini 2252674ae819SStefano Zampini /* Sum contributions from two levels */ 2253dc359a40SStefano Zampini if (applytranspose) { 2254dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2255dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2256dc359a40SStefano Zampini } else { 2257674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 22588eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2259dc359a40SStefano Zampini } 2260efc2fbd9SStefano Zampini /* store p0 */ 2261c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 2262efc2fbd9SStefano Zampini PetscScalar *array; 2263efc2fbd9SStefano Zampini 2264efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2265efc2fbd9SStefano Zampini pcbddc->benign_p0 = array[pcbddc->local_primal_size-1]; 2266efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2267efc2fbd9SStefano Zampini } 2268674ae819SStefano Zampini PetscFunctionReturn(0); 2269674ae819SStefano Zampini } 2270674ae819SStefano Zampini 2271674ae819SStefano Zampini #undef __FUNCT__ 2272674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 227312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2274674ae819SStefano Zampini { 2275674ae819SStefano Zampini PetscErrorCode ierr; 2276674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 227758da7f69SStefano Zampini PetscScalar *array; 227812edc857SStefano Zampini Vec from,to; 2279674ae819SStefano Zampini 2280674ae819SStefano Zampini PetscFunctionBegin; 228112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 228212edc857SStefano Zampini from = pcbddc->coarse_vec; 228312edc857SStefano Zampini to = pcbddc->vec1_P; 228412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 228512edc857SStefano Zampini Vec tvec; 228658da7f69SStefano Zampini 228758da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 228858da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 228912edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 229058da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 229158da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 229258da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 229312edc857SStefano Zampini } 229412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 229512edc857SStefano Zampini from = pcbddc->vec1_P; 229612edc857SStefano Zampini to = pcbddc->coarse_vec; 229712edc857SStefano Zampini } 229812edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 2299674ae819SStefano Zampini PetscFunctionReturn(0); 2300674ae819SStefano Zampini } 2301674ae819SStefano Zampini 2302674ae819SStefano Zampini #undef __FUNCT__ 2303674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 230412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 2305674ae819SStefano Zampini { 2306674ae819SStefano Zampini PetscErrorCode ierr; 2307674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 230858da7f69SStefano Zampini PetscScalar *array; 230912edc857SStefano Zampini Vec from,to; 2310674ae819SStefano Zampini 2311674ae819SStefano Zampini PetscFunctionBegin; 231212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 231312edc857SStefano Zampini from = pcbddc->coarse_vec; 231412edc857SStefano Zampini to = pcbddc->vec1_P; 231512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 231612edc857SStefano Zampini from = pcbddc->vec1_P; 231712edc857SStefano Zampini to = pcbddc->coarse_vec; 231812edc857SStefano Zampini } 231912edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 232012edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 232112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 232212edc857SStefano Zampini Vec tvec; 232358da7f69SStefano Zampini 232412edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 232558da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 232658da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 232758da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 232858da7f69SStefano Zampini } 232958da7f69SStefano Zampini } else { 233058da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 233158da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 233212edc857SStefano Zampini } 233312edc857SStefano Zampini } 2334674ae819SStefano Zampini PetscFunctionReturn(0); 2335674ae819SStefano Zampini } 2336674ae819SStefano Zampini 2337984c4197SStefano Zampini /* uncomment for testing purposes */ 2338984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 2339674ae819SStefano Zampini #undef __FUNCT__ 2340674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 2341674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 2342674ae819SStefano Zampini { 2343674ae819SStefano Zampini PetscErrorCode ierr; 2344674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2345674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2346674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2347984c4197SStefano Zampini /* one and zero */ 2348984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 2349984c4197SStefano Zampini /* space to store constraints and their local indices */ 23509162d606SStefano Zampini PetscScalar *constraints_data; 23519162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 23529162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 23539162d606SStefano Zampini PetscInt *constraints_n; 2354984c4197SStefano Zampini /* iterators */ 2355b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 2356984c4197SStefano Zampini /* BLAS integers */ 2357e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2358e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2359c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2360727cdba6SStefano Zampini /* reuse */ 23610e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 23620e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2363984c4197SStefano Zampini /* change of basis */ 2364b3d85658SStefano Zampini PetscBool qr_needed; 23659162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2366984c4197SStefano Zampini /* auxiliary stuff */ 236764efe560SStefano Zampini PetscInt *nnz,*is_indices; 23688a0068c3SStefano Zampini PetscInt ncc; 2369984c4197SStefano Zampini /* some quantities */ 237045a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2371a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2372984c4197SStefano Zampini 2373674ae819SStefano Zampini PetscFunctionBegin; 23748e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 23758e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 23768e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2377088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2378088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 23790e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 23800e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 23810e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 23820e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 23830e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2384088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2385cf5a6209SStefano Zampini 2386cf5a6209SStefano Zampini /* print some info */ 2387cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2388cf5a6209SStefano Zampini IS vertices; 2389cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2390cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2391cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2392cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2393cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2394cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2395cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2396fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2397fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2398cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2399cf5a6209SStefano Zampini } 2400cf5a6209SStefano Zampini 2401cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 24029162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2403cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2404cf5a6209SStefano Zampini const Vec *nearnullvecs; 2405cf5a6209SStefano Zampini Vec *localnearnullsp; 2406cf5a6209SStefano Zampini PetscScalar *array; 2407cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2408cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2409674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2410b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2411674ae819SStefano Zampini PetscScalar *work; 2412674ae819SStefano Zampini PetscReal *singular_vals; 2413674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2414674ae819SStefano Zampini PetscReal *rwork; 2415674ae819SStefano Zampini #endif 2416674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2417674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2418674ae819SStefano Zampini #else 2419964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2420964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2421674ae819SStefano Zampini #endif 2422674ae819SStefano Zampini 2423674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2424d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2425d06fc5fdSStefano Zampini /* free unneeded index sets */ 2426d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2427d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2428674ae819SStefano Zampini } 2429d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2430d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2431d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2432d06fc5fdSStefano Zampini } 2433d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2434d06fc5fdSStefano Zampini n_ISForEdges = 0; 2435d06fc5fdSStefano Zampini } 2436d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2437d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2438d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2439d06fc5fdSStefano Zampini } 2440d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2441d06fc5fdSStefano Zampini n_ISForFaces = 0; 2442d06fc5fdSStefano Zampini } 244370022509SStefano Zampini 244470022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 244570022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 244670022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 244770022509SStefano Zampini if (pcbddc->NullSpace) { 244870022509SStefano Zampini PetscBool tbool[2],gbool[2]; 244970022509SStefano Zampini 245070022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2451b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2452d06fc5fdSStefano Zampini if (!ISForEdges) { 2453d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2454d06fc5fdSStefano Zampini } 2455b8ffe317SStefano Zampini } 2456d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2457d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2458d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2459d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2460d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 246198a51de6SStefano Zampini } 246270022509SStefano Zampini #endif 246308122e43SStefano Zampini 2464674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2465674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2466674ae819SStefano Zampini if (nearnullsp) { 2467674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2468f4ddd8eeSStefano Zampini /* remove any stored info */ 2469f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2470f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2471f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2472f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2473f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2474473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2475f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2476f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2477f4ddd8eeSStefano Zampini } 2478984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2479984c4197SStefano Zampini nnsp_size = 0; 2480674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2481674ae819SStefano Zampini } 2482984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2483984c4197SStefano Zampini max_constraints = nnsp_size; 2484984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2485984c4197SStefano Zampini 2486674ae819SStefano Zampini /* 2487674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 24889162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 24899162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 24909162d606SStefano Zampini There can be multiple constraints per connected component 2491674ae819SStefano Zampini */ 2492674ae819SStefano Zampini n_vertices = 0; 2493674ae819SStefano Zampini if (ISForVertices) { 2494674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2495674ae819SStefano Zampini } 24969162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 24979162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 24989162d606SStefano Zampini 24999162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 25009162d606SStefano Zampini total_counts *= max_constraints; 2501674ae819SStefano Zampini total_counts += n_vertices; 25024641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 25039162d606SStefano Zampini 2504674ae819SStefano Zampini total_counts = 0; 2505674ae819SStefano Zampini max_size_of_constraint = 0; 2506674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 25079162d606SStefano Zampini IS used_is; 2508674ae819SStefano Zampini if (i<n_ISForEdges) { 25099162d606SStefano Zampini used_is = ISForEdges[i]; 2510674ae819SStefano Zampini } else { 25119162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2512674ae819SStefano Zampini } 25139162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2514674ae819SStefano Zampini total_counts += j; 2515674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2516674ae819SStefano Zampini } 25179162d606SStefano 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); 25189162d606SStefano Zampini 2519984c4197SStefano Zampini /* get local part of global near null space vectors */ 2520785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2521984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2522984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2523e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2524e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2525984c4197SStefano Zampini } 2526674ae819SStefano Zampini 2527242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2528242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2529a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2530242a89d7SStefano Zampini 2531984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2532a773dcb8SStefano Zampini if (!skip_lapack) { 2533674ae819SStefano Zampini PetscScalar temp_work; 2534911cabfeSStefano Zampini 2535674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2536984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2537785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2538785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2539785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2540674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2541785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2542674ae819SStefano Zampini #endif 2543674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2544c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2545c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2546674ae819SStefano Zampini lwork = -1; 2547674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2548674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2549c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2550674ae819SStefano Zampini #else 2551c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2552674ae819SStefano Zampini #endif 2553674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2554984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2555674ae819SStefano Zampini #else /* on missing GESVD */ 2556674ae819SStefano Zampini /* SVD */ 2557674ae819SStefano Zampini PetscInt max_n,min_n; 2558674ae819SStefano Zampini max_n = max_size_of_constraint; 2559984c4197SStefano Zampini min_n = max_constraints; 2560984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2561674ae819SStefano Zampini min_n = max_size_of_constraint; 2562984c4197SStefano Zampini max_n = max_constraints; 2563674ae819SStefano Zampini } 2564785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2565674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2566785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2567674ae819SStefano Zampini #endif 2568674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2569674ae819SStefano Zampini lwork = -1; 2570e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2571e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2572b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2573674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2574674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 25759162d606SStefano 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)); 2576674ae819SStefano Zampini #else 25779162d606SStefano 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)); 2578674ae819SStefano Zampini #endif 2579674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2580984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2581984c4197SStefano Zampini #endif /* on missing GESVD */ 2582674ae819SStefano Zampini /* Allocate optimal workspace */ 2583674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2584854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2585674ae819SStefano Zampini } 2586674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2587674ae819SStefano Zampini total_counts = 0; 25889162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 25899162d606SStefano Zampini constraints_data_ptr[0] = 0; 2590674ae819SStefano Zampini /* vertices */ 25919162d606SStefano Zampini if (n_vertices) { 2592674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 25939162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2594674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 25959162d606SStefano Zampini constraints_n[total_counts] = 1; 25969162d606SStefano Zampini constraints_data[total_counts] = 1.0; 25979162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 25989162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2599674ae819SStefano Zampini total_counts++; 2600674ae819SStefano Zampini } 2601674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2602674ae819SStefano Zampini n_vertices = total_counts; 2603674ae819SStefano Zampini } 2604984c4197SStefano Zampini 2605674ae819SStefano Zampini /* edges and faces */ 26069162d606SStefano Zampini total_counts_cc = total_counts; 2607911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 26089162d606SStefano Zampini IS used_is; 26099162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 26109162d606SStefano Zampini 2611911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 26129162d606SStefano Zampini used_is = ISForEdges[ncc]; 2613984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2614674ae819SStefano Zampini } else { 26159162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2616984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2617674ae819SStefano Zampini } 2618674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 26199162d606SStefano Zampini 26209162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 26219162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2622984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2623984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2624674ae819SStefano Zampini if (nnsp_has_cnst) { 26255b08dc53SStefano Zampini PetscScalar quad_value; 26269162d606SStefano Zampini 26279162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 26289162d606SStefano Zampini idxs_copied = PETSC_TRUE; 26299162d606SStefano Zampini 2630a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2631674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2632a773dcb8SStefano Zampini } else { 2633a773dcb8SStefano Zampini quad_value = 1.0; 2634a773dcb8SStefano Zampini } 2635674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 26369162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 2637674ae819SStefano Zampini } 26389162d606SStefano Zampini temp_constraints++; 2639674ae819SStefano Zampini total_counts++; 2640674ae819SStefano Zampini } 2641674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2642984c4197SStefano Zampini PetscReal real_value; 26439162d606SStefano Zampini PetscScalar *ptr_to_data; 26449162d606SStefano Zampini 2645984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 26469162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 2647674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 26489162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 2649674ae819SStefano Zampini } 2650984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2651984c4197SStefano Zampini /* check if array is null on the connected component */ 2652e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 26539162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 26545b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2655674ae819SStefano Zampini temp_constraints++; 2656674ae819SStefano Zampini total_counts++; 26579162d606SStefano Zampini if (!idxs_copied) { 26589162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 26599162d606SStefano Zampini idxs_copied = PETSC_TRUE; 2660674ae819SStefano Zampini } 2661674ae819SStefano Zampini } 26629162d606SStefano Zampini } 26639162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 266445a1bb75SStefano Zampini valid_constraints = temp_constraints; 2665eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2666a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 26679162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 26689162d606SStefano Zampini 26699162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2670a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 26719162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 2672a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 26739162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 2674a773dcb8SStefano Zampini } else { /* perform SVD */ 2675984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 26769162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2677674ae819SStefano Zampini 2678674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2679984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 2680984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 2681984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 2682984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 2683984c4197SStefano Zampini from that computed using LAPACKgesvd 2684984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 2685984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 2686984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 2687674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 2688e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2689984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2690674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 2691674ae819SStefano Zampini for (k=0;k<j+1;k++) { 26929162d606SStefano 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)); 2693674ae819SStefano Zampini } 2694674ae819SStefano Zampini } 2695e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 2696e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2697e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 2698674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2699c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 2700674ae819SStefano Zampini #else 2701c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 2702674ae819SStefano Zampini #endif 2703674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2704984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 2705984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 2706674ae819SStefano Zampini j = 0; 2707984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 2708674ae819SStefano Zampini total_counts = total_counts-j; 270945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 2710e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 2711c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2712c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2713c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 2714c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2715c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 2716c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2717674ae819SStefano Zampini if (j<temp_constraints) { 2718984c4197SStefano Zampini PetscInt ii; 2719984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 2720674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27219162d606SStefano 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)); 2722674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2723984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 2724674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 27259162d606SStefano 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]; 2726674ae819SStefano Zampini } 2727674ae819SStefano Zampini } 2728674ae819SStefano Zampini } 2729674ae819SStefano Zampini #else /* on missing GESVD */ 2730e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2731e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2732b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2733674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2734674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 27359162d606SStefano 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)); 2736674ae819SStefano Zampini #else 27379162d606SStefano 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)); 2738674ae819SStefano Zampini #endif 2739984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 2740674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2741984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 2742e310c8b4SStefano Zampini k = temp_constraints; 2743e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 2744674ae819SStefano Zampini j = 0; 2745e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 274645a1bb75SStefano Zampini valid_constraints = k-j; 2747911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 2748984c4197SStefano Zampini #endif /* on missing GESVD */ 2749674ae819SStefano Zampini } 2750a773dcb8SStefano Zampini } 27519162d606SStefano Zampini /* update pointers information */ 27529162d606SStefano Zampini if (valid_constraints) { 27539162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 27549162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 27559162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 27569162d606SStefano Zampini /* set change_of_basis flag */ 275745a1bb75SStefano Zampini if (boolforchange) { 2758b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 27599162d606SStefano Zampini } 2760b3d85658SStefano Zampini total_counts_cc++; 276145a1bb75SStefano Zampini } 276245a1bb75SStefano Zampini } 2763984c4197SStefano Zampini /* free workspace */ 27648f1c130eSStefano Zampini if (!skip_lapack) { 2765984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2766984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2767984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 2768984c4197SStefano Zampini #endif 2769984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 2770984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2771984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 2772984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 2773984c4197SStefano Zampini #endif 2774984c4197SStefano Zampini } 2775984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2776984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 2777984c4197SStefano Zampini } 2778984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 2779cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 2780cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2781cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2782cf5a6209SStefano Zampini } 2783cf5a6209SStefano Zampini if (n_ISForFaces) { 2784cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2785cf5a6209SStefano Zampini } 2786cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2787cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2788cf5a6209SStefano Zampini } 2789cf5a6209SStefano Zampini if (n_ISForEdges) { 2790cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2791cf5a6209SStefano Zampini } 2792cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 279308122e43SStefano Zampini } else { 279408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2795984c4197SStefano Zampini 279608122e43SStefano Zampini total_counts = 0; 279708122e43SStefano Zampini n_vertices = 0; 2798d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 2799d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 280008122e43SStefano Zampini } 280108122e43SStefano Zampini max_constraints = 0; 28029162d606SStefano Zampini total_counts_cc = 0; 280308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 280408122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 28059162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 280608122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 280708122e43SStefano Zampini } 28089162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 28099162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 28109162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 28119162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 281274d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 28139162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 28149162d606SStefano Zampini total_counts_cc = 0; 28159162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 28169162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 28179162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 281808122e43SStefano Zampini } 281908122e43SStefano Zampini } 28209162d606SStefano Zampini #if 0 28219162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 28229162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 28239162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 28249162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 28259162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 28269162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 28279162d606SStefano Zampini } 28289162d606SStefano Zampini printf("\n"); 28299162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 28309162d606SStefano Zampini } 28311b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 28328bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 28331b968477SStefano Zampini } 28341b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 28358bec7fa6SStefano 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]); 28361b968477SStefano Zampini } 283708122e43SStefano Zampini #endif 283808122e43SStefano Zampini 28398bec7fa6SStefano Zampini max_size_of_constraint = 0; 28409162d606SStefano 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]); 28419162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 284208122e43SStefano Zampini /* Change of basis */ 2843b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 284408122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 284508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 284608122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 2847b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 284808122e43SStefano Zampini } 284908122e43SStefano Zampini } 285008122e43SStefano Zampini } 285108122e43SStefano Zampini } 2852984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 2853019a44ceSStefano Zampini /* allocating one extra space (in case an extra primal dof should be stored for the benign trick */ 2854019a44ceSStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+1,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 285508122e43SStefano Zampini 28569162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 28579162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 28589162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 28599162d606SStefano 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); 286008122e43SStefano Zampini } 2861674ae819SStefano Zampini 2862674ae819SStefano Zampini /* Create constraint matrix */ 2863674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 286416f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 2865984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 2866984c4197SStefano Zampini 2867984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 2868a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 2869a717540cSStefano Zampini qr_needed = PETSC_FALSE; 287074d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 2871984c4197SStefano Zampini total_primal_vertices=0; 2872b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 28739162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 28749162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 2875984c4197SStefano Zampini if (size_of_constraint == 1) { 28769162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 2877b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 287864efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 28799162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 28809162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 2881a717540cSStefano Zampini } 2882b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 288374d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 2884a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 2885a717540cSStefano Zampini qr_needed = PETSC_TRUE; 2886a717540cSStefano Zampini } 2887fa434743SStefano Zampini } else { 2888b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 2889fa434743SStefano Zampini } 2890a717540cSStefano Zampini } 2891b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 2892b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 2893674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 289470022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2895b3d85658SStefano Zampini 2896019a44ceSStefano Zampini /* allocating one extra space (in case an extra primal dof should be stored for the benign trick */ 2897019a44ceSStefano 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); 28980e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 28990e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 2900984c4197SStefano Zampini 2901984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 290274d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 2903785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2904984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 290574d5cdf7SStefano Zampini 2906984c4197SStefano Zampini j = total_primal_vertices; 290774d5cdf7SStefano Zampini total_counts = total_primal_vertices; 2908b3d85658SStefano Zampini cum = total_primal_vertices; 29099162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 29104641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2911b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 2912b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 2913b3d85658SStefano Zampini cum++; 29149162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 291574d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 291674d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 291774d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 291874d5cdf7SStefano Zampini } 29199162d606SStefano Zampini j += constraints_n[i]; 2920674ae819SStefano Zampini } 2921674ae819SStefano Zampini } 2922674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2923674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2924088faed8SStefano Zampini 2925674ae819SStefano Zampini /* set values in constraint matrix */ 2926984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 29270e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2928674ae819SStefano Zampini } 2929984c4197SStefano Zampini total_counts = total_primal_vertices; 29309162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 29314641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 29329162d606SStefano Zampini PetscInt *cols; 29339162d606SStefano Zampini 29349162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 29359162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 29369162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 29379162d606SStefano Zampini PetscInt row = total_counts+k; 29389162d606SStefano Zampini PetscScalar *vals; 29399162d606SStefano Zampini 29409162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 29419162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 29429162d606SStefano Zampini } 29439162d606SStefano Zampini total_counts += constraints_n[i]; 2944674ae819SStefano Zampini } 2945674ae819SStefano Zampini } 2946674ae819SStefano Zampini /* assembling */ 2947674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2948674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2949088faed8SStefano Zampini 2950984c4197SStefano Zampini /* 295145a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2952984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2953984c4197SStefano Zampini */ 2954674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2955674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2956026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2957984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2958984c4197SStefano Zampini /* working stuff for GEQRF */ 295981d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2960984c4197SStefano Zampini PetscBLASInt lqr_work; 2961984c4197SStefano Zampini /* working stuff for UNGQR */ 2962984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2963984c4197SStefano Zampini PetscBLASInt lgqr_work; 2964984c4197SStefano Zampini /* working stuff for TRTRS */ 2965984c4197SStefano Zampini PetscScalar *trs_rhs; 29663f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2967984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2968984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2969984c4197SStefano Zampini PetscScalar *start_vals; 2970984c4197SStefano Zampini /* working stuff for values insertion */ 29714641a718SStefano Zampini PetscBT is_primal; 297264efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 2973906d46d4SStefano Zampini /* matrix sizes */ 2974906d46d4SStefano Zampini PetscInt global_size,local_size; 2975906d46d4SStefano Zampini /* temporary change of basis */ 2976906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2977cf5a6209SStefano Zampini /* extra space for debugging */ 2978cf5a6209SStefano Zampini PetscScalar *dbg_work; 2979984c4197SStefano Zampini 2980906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2981906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 298216f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2983bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 2984906d46d4SStefano Zampini /* nonzeros for local mat */ 2985bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 2986bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 29879162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 2988a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 29899162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 2990a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 29919162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 2992a717540cSStefano Zampini } else { 29939162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 29949162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 2995a717540cSStefano Zampini } 2996a717540cSStefano Zampini } 2997a717540cSStefano Zampini } 2998906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2999bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3000a717540cSStefano Zampini /* Set initial identity in the matrix */ 3001bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3002906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3003a717540cSStefano Zampini } 3004a717540cSStefano Zampini 3005a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3006a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3007a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3008a717540cSStefano Zampini } 3009a717540cSStefano Zampini 3010a717540cSStefano Zampini 3011a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3012a717540cSStefano Zampini /* 3013a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3014a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3015a717540cSStefano Zampini 3016a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3017a717540cSStefano Zampini 3018a6b551f4SStefano 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) 3019a6b551f4SStefano Zampini 3020a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3021a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3022a717540cSStefano Zampini | ... | 3023a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3024a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3025a717540cSStefano Zampini 3026a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3027a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3028a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3029a6b551f4SStefano Zampini 3030a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3031a717540cSStefano Zampini */ 3032a717540cSStefano Zampini if (qr_needed) { 3033984c4197SStefano Zampini /* space to store Q */ 3034854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3035984c4197SStefano Zampini /* first we issue queries for optimal work */ 30363f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 30373f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 30383f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3039984c4197SStefano Zampini lqr_work = -1; 30403f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3041984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3042984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3043785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3044984c4197SStefano Zampini lgqr_work = -1; 30453f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 30463f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 30473f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 30483f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 30493f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 30503f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3051984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3052984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3053785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3054984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3055785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3056984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3057785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3058a717540cSStefano Zampini /* allocating workspace for check */ 3059a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3060cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3061a717540cSStefano Zampini } 3062a717540cSStefano Zampini } 3063984c4197SStefano Zampini /* array to store whether a node is primal or not */ 30644641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3065473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 30660e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 306739e2fb2aSStefano Zampini if (i != total_primal_vertices) { 306839e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 30694641a718SStefano Zampini } 307039e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 307139e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 307239e2fb2aSStefano Zampini } 307339e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3074984c4197SStefano Zampini 3075a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 30769162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 30779162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 30784641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3079984c4197SStefano Zampini /* get constraint info */ 30809162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3081984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3082984c4197SStefano Zampini 3083984c4197SStefano Zampini if (pcbddc->dbg_flag) { 30849162d606SStefano 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); 3085674ae819SStefano Zampini } 3086984c4197SStefano Zampini 3087fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3088a717540cSStefano Zampini 3089a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3090a717540cSStefano Zampini if (pcbddc->dbg_flag) { 30919162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3092a717540cSStefano Zampini } 3093984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 30949162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3095984c4197SStefano Zampini 3096984c4197SStefano Zampini /* compute QR decomposition of constraints */ 30973f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 30983f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 30993f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3100674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31013f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3102984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3103674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3104984c4197SStefano Zampini 3105984c4197SStefano Zampini /* explictly compute R^-T */ 3106984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3107984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 31083f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 31093f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 31103f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 31113f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3112984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31133f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3114984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3115984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3116984c4197SStefano Zampini 3117a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 31183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 31193f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 31203f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 31213f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3122984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31233f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3124984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3125984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3126984c4197SStefano Zampini 3127984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3128984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3129984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 31303f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 31313f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 31323f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 31333f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 31343f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 31353f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3136984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31379162d606SStefano 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)); 3138984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 31399162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3140984c4197SStefano Zampini 3141984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 31429162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3143984c4197SStefano Zampini /* insert cols for primal dofs */ 3144984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3145984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 31469162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3147906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3148984c4197SStefano Zampini } 3149984c4197SStefano Zampini /* insert cols for dual dofs */ 3150984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 31519162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3152984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 31539162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3154906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3155984c4197SStefano Zampini j++; 3156674ae819SStefano Zampini } 3157674ae819SStefano Zampini } 3158984c4197SStefano Zampini 3159984c4197SStefano Zampini /* check change of basis */ 3160984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3161984c4197SStefano Zampini PetscInt ii,jj; 3162984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3163c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3164c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3165c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3166c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3167c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3168c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3169984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3170cf5a6209SStefano 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)); 3171984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3172984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3173984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3174cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3175cf5a6209SStefano 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; 3176674ae819SStefano Zampini } 3177674ae819SStefano Zampini } 3178984c4197SStefano Zampini if (!valid_qr) { 317922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3180984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3181984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3182cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3183cf5a6209SStefano 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])); 3184674ae819SStefano Zampini } 3185cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3186cf5a6209SStefano 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])); 3187984c4197SStefano Zampini } 3188984c4197SStefano Zampini } 3189984c4197SStefano Zampini } 3190674ae819SStefano Zampini } else { 319122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3192674ae819SStefano Zampini } 3193674ae819SStefano Zampini } 3194a717540cSStefano Zampini } else { /* simple transformation block */ 3195a717540cSStefano Zampini PetscInt row,col; 3196a6b551f4SStefano Zampini PetscScalar val,norm; 3197a6b551f4SStefano Zampini 3198a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 31999162d606SStefano 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)); 3200a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 32019162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 32029162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3203bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 32049162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3205906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 32069162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3207a717540cSStefano Zampini } else { 3208a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 32099162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3210a717540cSStefano Zampini if (row != col) { 32119162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3212a717540cSStefano Zampini } else { 32139162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3214a717540cSStefano Zampini } 3215906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3216a717540cSStefano Zampini } 3217a717540cSStefano Zampini } 3218a717540cSStefano Zampini } 321998a51de6SStefano Zampini if (pcbddc->dbg_flag) { 322022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3221a717540cSStefano Zampini } 3222674ae819SStefano Zampini } 3223984c4197SStefano Zampini } else { 3224984c4197SStefano Zampini if (pcbddc->dbg_flag) { 32259162d606SStefano 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); 3226674ae819SStefano Zampini } 3227674ae819SStefano Zampini } 3228674ae819SStefano Zampini } 3229a717540cSStefano Zampini 3230a717540cSStefano Zampini /* free workspace */ 3231a717540cSStefano Zampini if (qr_needed) { 3232984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3233cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3234984c4197SStefano Zampini } 3235984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3236984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3237984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3238984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3239984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3240674ae819SStefano Zampini } 3241a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3242906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3243906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3244906d46d4SStefano Zampini 3245906d46d4SStefano Zampini /* assembling of global change of variable */ 3246bbb9e6c6SStefano Zampini { 3247bbb9e6c6SStefano Zampini Mat tmat; 324816f15bc4SStefano Zampini PetscInt bs; 324916f15bc4SStefano Zampini 3250906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3251906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3252bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3253bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3254bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3255bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 325616f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 325716f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3258906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3259bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3260bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3261bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3262bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3263bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3264e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3265e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3266bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3267bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3268906d46d4SStefano Zampini } 3269906d46d4SStefano Zampini /* check */ 3270906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3271906d46d4SStefano Zampini PetscReal error; 3272906d46d4SStefano Zampini Vec x,x_change; 3273906d46d4SStefano Zampini 3274906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3275906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3276906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3277906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3278e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3279e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3280bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 3281e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3282e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3283906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 3284906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3285906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3286906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3287bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 3288906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3289906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3290906d46d4SStefano Zampini } 3291b96c3477SStefano Zampini 3292b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 3293b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3294b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 3295b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 3296ac632422SStefano Zampini Mat S_new,tmat; 3297b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 3298b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 3299b087196eSStefano Zampini const PetscScalar *array; 3300b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 3301b087196eSStefano Zampini PetscInt i,n_V; 3302bbb9e6c6SStefano Zampini 3303bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 33046816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 3305b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 3306b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 3307b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 3308b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 3309bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 3310b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 3311ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3312b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 3313ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3314b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3315b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 3316b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3317b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3318b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 3319b087196eSStefano Zampini for (i=0;i<n_V;i++) { 3320b087196eSStefano Zampini PetscScalar val; 3321b087196eSStefano Zampini PetscInt idx; 3322b087196eSStefano Zampini 3323b087196eSStefano Zampini idx = idxs_V[i]; 3324b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 3325b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 3326b087196eSStefano Zampini } 3327b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3328b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3329ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 3330ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3331ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 3332ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3333b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 3334ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3335b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3336ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 3337ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3338ac632422SStefano Zampini } 3339b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 3340b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3341b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3342b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3343b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 3344b96c3477SStefano Zampini } 3345b96c3477SStefano Zampini } 3346906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 3347906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 3348b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3349b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 3350b9b85e73SStefano Zampini } 3351906d46d4SStefano Zampini 3352906d46d4SStefano Zampini /* set up change of basis context */ 3353906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 3354906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 3355906d46d4SStefano Zampini 3356906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 3357906d46d4SStefano Zampini PetscInt global_size,local_size; 3358906d46d4SStefano Zampini 3359906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3360906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3361906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 3362906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3363906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 3364906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 3365906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3366906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3367906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3368906d46d4SStefano Zampini } else { 3369906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3370906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3371906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3372906d46d4SStefano Zampini } 3373906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3374906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3375906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3376906d46d4SStefano Zampini } else { 3377906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3378906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3379906d46d4SStefano Zampini } 3380906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3381906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3382906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3383906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3384b9b85e73SStefano Zampini } 3385a717540cSStefano Zampini 3386019a44ceSStefano Zampini /* add pressure dof to set of primal nodes for numbering purposes */ 3387c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 3388c9ed8603SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx; 3389d16cbb6bSStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx; 3390019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 3391019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 3392019a44ceSStefano Zampini pcbddc->local_primal_size++; 3393019a44ceSStefano Zampini } 3394019a44ceSStefano Zampini 3395019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 3396727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3397727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 3398aff50787SStefano 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); 3399c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 34000e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 3401aff50787SStefano 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); 3402727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3403727cdba6SStefano Zampini } 34040e6343abSStefano Zampini } 34050e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3406727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3407727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3408727cdba6SStefano Zampini 3409a717540cSStefano Zampini /* flush dbg viewer */ 3410b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3411b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3412b8ffe317SStefano Zampini } 3413a717540cSStefano Zampini 3414e310c8b4SStefano Zampini /* free workspace */ 3415a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 34164641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 341708122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 34189162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 34199162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 342008122e43SStefano Zampini } else { 34219162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 34229162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 34239162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 342408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 342508122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 34269162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 34279162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 342808122e43SStefano Zampini } 3429674ae819SStefano Zampini PetscFunctionReturn(0); 3430674ae819SStefano Zampini } 3431674ae819SStefano Zampini 3432674ae819SStefano Zampini #undef __FUNCT__ 3433674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3434674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3435674ae819SStefano Zampini { 3436674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3437674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3438674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 34397fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3440674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3441674ae819SStefano Zampini 3442674ae819SStefano Zampini PetscFunctionBegin; 34438e61c736SStefano Zampini /* Reset previously computed graph */ 34448e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3445674ae819SStefano Zampini /* Init local Graph struct */ 34467fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 34473bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3448674ae819SStefano Zampini 3449575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 34505099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 34515099eff2SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid size of local CSR graph! Found %d, expected %d\n",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 3452575ad6abSStefano Zampini } 34539577ea80SStefano Zampini 3454674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 34554d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 34564d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 34574d379d7bSStefano Zampini PetscInt nvtxs; 3458e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3459674ae819SStefano Zampini 34604d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 34612fffb893SStefano Zampini 34622fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34632fffb893SStefano Zampini if (flg_row) { 34644d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3465b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 34662fffb893SStefano Zampini } 34672fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34689b28b941SStefano 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 */ 34694d379d7bSStefano Zampini IS is_dummy; 34704d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 34714d379d7bSStefano Zampini PetscInt j,sum; 34724d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 34734d379d7bSStefano Zampini const PetscInt *idxs; 34744d379d7bSStefano Zampini PCBDDCGraph graph; 34754d379d7bSStefano Zampini PetscBT is_on_boundary; 34764d379d7bSStefano Zampini 34774d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 34784d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 34794d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 34804d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 34817fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 34824d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3483e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3484e496cd5dSStefano Zampini if (flg_row) { 34854d379d7bSStefano Zampini graph->xadj = xadj; 34864d379d7bSStefano Zampini graph->adjncy = adjncy; 3487e496cd5dSStefano Zampini } 34884d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 34894d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3490e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34914d379d7bSStefano Zampini 34924d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 34939b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 34944d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 34954d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 34964d379d7bSStefano Zampini } 34974d379d7bSStefano Zampini } 34984d379d7bSStefano Zampini 3499e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 35004d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 35014d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 35024d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 35034d379d7bSStefano Zampini } 35044d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 35054d379d7bSStefano Zampini 3506e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 35074d379d7bSStefano Zampini sum = 0; 35084d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 35094d379d7bSStefano Zampini PetscInt sizecc = 0; 35104d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 35114d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 35124d379d7bSStefano Zampini sizecc++; 35134d379d7bSStefano Zampini } 35144d379d7bSStefano Zampini } 35154d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 35164d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 35174d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 35184d379d7bSStefano Zampini } 35194d379d7bSStefano Zampini } 35204d379d7bSStefano Zampini sum += sizecc*sizecc; 35214d379d7bSStefano Zampini } 35224d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 35234d379d7bSStefano Zampini sum = 0; 3524e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 35254d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 35264d379d7bSStefano Zampini cxadj[i] = sum; 35274d379d7bSStefano Zampini sum += temp; 35284d379d7bSStefano Zampini } 3529e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 35304d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 35314d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 35324d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 35334d379d7bSStefano Zampini PetscInt k,sizecc = 0; 35344d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 35354d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 35364d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 35374d379d7bSStefano Zampini sizecc++; 35384d379d7bSStefano Zampini } 35394d379d7bSStefano Zampini } 35404d379d7bSStefano Zampini } 35414d379d7bSStefano Zampini } 35424d379d7bSStefano Zampini } 35439b28b941SStefano Zampini if (sum) { 3544e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 35454d379d7bSStefano Zampini } else { 35464d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 35474d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 35484d379d7bSStefano Zampini } 35494d379d7bSStefano Zampini graph->xadj = 0; 35504d379d7bSStefano Zampini graph->adjncy = 0; 35514d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 35524d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 35534d379d7bSStefano Zampini } 3554674ae819SStefano Zampini } 35559b28b941SStefano Zampini if (pcbddc->dbg_flag) { 35569b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3557674ae819SStefano Zampini } 3558674ae819SStefano Zampini 355963602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3560674ae819SStefano Zampini vertex_size = 1; 356163602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 356263602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 356395ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 356463602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3565e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 356663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3567674ae819SStefano Zampini } 356863602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 356963602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 357063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3571674ae819SStefano Zampini } 357263602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3573674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 357463602bcaSStefano Zampini } else { 357563602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 357663602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3577854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 357863602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 357963602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 358063602bcaSStefano Zampini } 358163602bcaSStefano Zampini } 3582674ae819SStefano Zampini } 3583674ae819SStefano Zampini 3584674ae819SStefano Zampini /* Setup of Graph */ 3585785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3586e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3587785d1243SStefano Zampini } 3588785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3589e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3590785d1243SStefano Zampini } 3591302440fdSBarry Smith ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices);CHKERRQ(ierr); 3592674ae819SStefano Zampini 3593674ae819SStefano Zampini /* Graph's connected components analysis */ 3594674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3595674ae819SStefano Zampini 3596674ae819SStefano Zampini /* print some info to stdout */ 3597674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3598302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3599674ae819SStefano Zampini } 3600fb180af4SStefano Zampini 3601fb180af4SStefano Zampini /* mark topography has done */ 3602fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3603674ae819SStefano Zampini PetscFunctionReturn(0); 3604674ae819SStefano Zampini } 3605674ae819SStefano Zampini 3606dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3607674ae819SStefano Zampini #undef __FUNCT__ 3608674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3609dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3610674ae819SStefano Zampini { 3611dc456d91SStefano Zampini PetscSF sf; 3612dc456d91SStefano Zampini PetscLayout map; 3613dc456d91SStefano Zampini const PetscInt *idxs; 3614dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 3615dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 3616dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 3617dc456d91SStefano Zampini PetscMPIInt commsize; 3618674ae819SStefano Zampini PetscBool first_found; 3619674ae819SStefano Zampini PetscErrorCode ierr; 3620674ae819SStefano Zampini 3621674ae819SStefano Zampini PetscFunctionBegin; 3622dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 3623dc456d91SStefano Zampini if (subset_mult) { 3624dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 3625dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 3626dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 3627674ae819SStefano Zampini } 3628dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 3629dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 3630dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 3631dc456d91SStefano Zampini for (i=0;i<n;i++) { 3632dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 3633dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 3634674ae819SStefano Zampini } 3635dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 3636dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3637dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 3638dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 3639dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 3640dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 3641dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 3642dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 3643dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 3644dc456d91SStefano Zampini 3645dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 3646dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 3647dc456d91SStefano Zampini if (subset_mult) { 3648dc456d91SStefano Zampini const PetscInt* idxs_mult; 3649dc456d91SStefano Zampini 3650dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3651dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 3652dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3653674ae819SStefano Zampini } else { 3654dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 3655674ae819SStefano Zampini } 3656dc456d91SStefano Zampini /* local size of new subset */ 3657dc456d91SStefano Zampini n_n = 0; 3658dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 3659dc456d91SStefano Zampini 3660dc456d91SStefano Zampini /* global indexes in layout */ 3661dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 3662dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 3663dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 3664dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 3665dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 3666dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 3667dc456d91SStefano Zampini 3668dc456d91SStefano Zampini /* reduce from leaves to roots */ 3669dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 367064a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 367164a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 3672dc456d91SStefano Zampini 3673dc456d91SStefano Zampini /* count indexes in local part of layout */ 3674674ae819SStefano Zampini nlocals = 0; 3675674ae819SStefano Zampini first_index = -1; 3676674ae819SStefano Zampini first_found = PETSC_FALSE; 3677dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 3678dc456d91SStefano Zampini if (!first_found && root_data[i]) { 3679674ae819SStefano Zampini first_found = PETSC_TRUE; 3680674ae819SStefano Zampini first_index = i; 3681674ae819SStefano Zampini } 3682dc456d91SStefano Zampini nlocals += root_data[i]; 3683674ae819SStefano Zampini } 3684dc456d91SStefano Zampini 3685dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 36865fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 3687dc456d91SStefano Zampini start = 0; 368864a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 36895fa240b1SStefano Zampini #else 369064a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 36915fa240b1SStefano Zampini start = start-nlocals; 36925fa240b1SStefano Zampini #endif 36935fa240b1SStefano Zampini 3694dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 3695dc456d91SStefano Zampini *N_n = start + nlocals; 3696dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 3697dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3698674ae819SStefano Zampini } 36995fa240b1SStefano Zampini 37005fa240b1SStefano Zampini /* adapt root data with cumulative */ 3701674ae819SStefano Zampini if (first_found) { 3702dc456d91SStefano Zampini PetscInt old_index; 3703dc456d91SStefano Zampini 3704dc456d91SStefano Zampini root_data[first_index] += start; 3705674ae819SStefano Zampini old_index = first_index; 3706dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 3707dc456d91SStefano Zampini if (root_data[i]) { 3708dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 3709674ae819SStefano Zampini old_index = i; 3710674ae819SStefano Zampini } 3711674ae819SStefano Zampini } 3712674ae819SStefano Zampini } 3713dc456d91SStefano Zampini 3714dc456d91SStefano Zampini /* from roots to leaves */ 3715dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3716dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3717dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 3718dc456d91SStefano Zampini 3719dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 3720dc456d91SStefano Zampini if (subset_mult) { 3721dc456d91SStefano Zampini const PetscInt* idxs_mult; 3722dc456d91SStefano Zampini PetscInt cum; 3723dc456d91SStefano Zampini 3724dc456d91SStefano Zampini cum = 0; 3725dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3726dc456d91SStefano Zampini for (i=0;i<n;i++) { 3727dc456d91SStefano Zampini PetscInt j; 3728dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 3729674ae819SStefano Zampini } 3730dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3731674ae819SStefano Zampini } else { 3732dc456d91SStefano Zampini for (i=0;i<n;i++) { 3733dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 3734674ae819SStefano Zampini } 3735674ae819SStefano Zampini } 3736dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 3737dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 3738674ae819SStefano Zampini PetscFunctionReturn(0); 3739674ae819SStefano Zampini } 37409a7d3425SStefano Zampini 37419a7d3425SStefano Zampini #undef __FUNCT__ 37429a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 37439a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 37449a7d3425SStefano Zampini { 37459a7d3425SStefano Zampini PetscInt i,j; 37469a7d3425SStefano Zampini PetscScalar *alphas; 37479a7d3425SStefano Zampini PetscErrorCode ierr; 37489a7d3425SStefano Zampini 37499a7d3425SStefano Zampini PetscFunctionBegin; 37509a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 3751785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 37529a7d3425SStefano Zampini for (i=0;i<n;i++) { 37539a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 37549a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 37559a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 37569a7d3425SStefano Zampini } 37579a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 37589a7d3425SStefano Zampini PetscFunctionReturn(0); 37599a7d3425SStefano Zampini } 37609a7d3425SStefano Zampini 3761e7931f94SStefano Zampini #undef __FUNCT__ 376270cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 3763b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 3764e7931f94SStefano Zampini { 376552e5ac9dSStefano Zampini IS ranks_send_to; 3766e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 3767e7931f94SStefano Zampini PetscMPIInt size,rank,color; 376852e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 376952e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 37703837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 37712b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 3772e7931f94SStefano Zampini PetscSubcomm subcomm; 377352e5ac9dSStefano Zampini PetscErrorCode ierr; 3774a57a6d2fSStefano Zampini 3775e7931f94SStefano Zampini PetscFunctionBegin; 37762b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 37772b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 37782b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 3779e7931f94SStefano Zampini 3780e7931f94SStefano Zampini /* Get info on mapping */ 37813bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 37823bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3783e7931f94SStefano Zampini 3784e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 3785785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 3786e7931f94SStefano Zampini xadj[0] = 0; 3787e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 3788785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 3789785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 3790e7931f94SStefano Zampini 37912b510759SStefano Zampini if (threshold) { 3792d023bfaeSStefano Zampini PetscInt xadj_count = 0; 37932b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 3794d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 3795d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 3796d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 3797d023bfaeSStefano Zampini xadj_count++; 3798e7931f94SStefano Zampini } 3799e7931f94SStefano Zampini } 3800d023bfaeSStefano Zampini xadj[1] = xadj_count; 3801c8587f34SStefano Zampini } else { 3802e7931f94SStefano Zampini if (xadj[1]) { 3803e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 3804e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 3805c8587f34SStefano Zampini } 3806e7931f94SStefano Zampini } 38073bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3808e7931f94SStefano Zampini if (use_square) { 3809e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3810e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3811e7931f94SStefano Zampini } 3812e7931f94SStefano Zampini } 3813e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3814e7931f94SStefano Zampini 38153837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3816e7931f94SStefano Zampini 3817e7931f94SStefano Zampini /* 3818e7931f94SStefano Zampini Restrict work on active processes only. 3819e7931f94SStefano Zampini */ 3820e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3821e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3822e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 38232b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3824d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3825e7931f94SStefano Zampini if (color) { 3826e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3827e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3828e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3829c8587f34SStefano Zampini } else { 383052e5ac9dSStefano Zampini Mat subdomain_adj; 383152e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 383252e5ac9dSStefano Zampini MatPartitioning partitioner; 383352e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 383452e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 3835b0c7d250SStefano Zampini PetscBool aggregate; 3836b0c7d250SStefano Zampini 3837306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 3838785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3839e7931f94SStefano Zampini prank = rank; 3840306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 38418002ef2cSStefano Zampini /* 3842e7931f94SStefano Zampini for (i=0;i<size;i++) { 3843e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3844c8587f34SStefano Zampini } 38458002ef2cSStefano Zampini */ 3846e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3847e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3848c8587f34SStefano Zampini } 3849e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3850b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 3851b0c7d250SStefano Zampini if (aggregate) { 3852b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 3853b0c7d250SStefano Zampini PetscMPIInt nrank; 3854b0c7d250SStefano Zampini PetscScalar *vals; 3855b0c7d250SStefano Zampini 3856b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 3857b0c7d250SStefano Zampini lrows = 0; 3858b0c7d250SStefano Zampini if (nrank<redprocs) { 3859b0c7d250SStefano Zampini lrows = size/redprocs; 3860b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 3861b0c7d250SStefano Zampini } 38625fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 3863b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 3864b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3865b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3866b0c7d250SStefano Zampini row = nrank; 3867b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 3868b0c7d250SStefano Zampini cols = adjncy; 3869b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 3870b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 3871b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 3872b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3873b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 387452e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 387552e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 387652e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3877b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 3878b0c7d250SStefano Zampini } else { 3879306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 3880b0c7d250SStefano Zampini } 388122b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3882e7931f94SStefano Zampini 3883e7931f94SStefano Zampini /* Partition */ 3884306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 3885e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3886e7931f94SStefano Zampini if (use_vwgt) { 38873837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3888e7931f94SStefano Zampini v_wgt[0] = local_size; 3889e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3890c8587f34SStefano Zampini } 389128143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 389228143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3893e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3894e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 389522b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3896e7931f94SStefano Zampini 389752e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 389852e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 389952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 390052e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3901b0c7d250SStefano Zampini if (!redprocs) { 3902b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 390328143c3dSStefano Zampini } else { 3904b0c7d250SStefano Zampini PetscInt idxs[1]; 3905b0c7d250SStefano Zampini PetscMPIInt tag; 3906b0c7d250SStefano Zampini MPI_Request *reqs; 3907b0c7d250SStefano Zampini 3908b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 3909b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 3910b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 3911b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 391228143c3dSStefano Zampini } 3913b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 3914b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3915b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 3916b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 3917e7931f94SStefano Zampini } 391852e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3919e7931f94SStefano Zampini /* clean up */ 3920e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 392152e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 3922e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3923e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3924e7931f94SStefano Zampini } 3925e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3926e7931f94SStefano Zampini 3927e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3928e7931f94SStefano Zampini i = 1; 3929e7931f94SStefano Zampini if (color) i=0; 3930e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3931e7931f94SStefano Zampini /* get back IS */ 3932e7931f94SStefano Zampini *is_sends = ranks_send_to; 3933e7931f94SStefano Zampini PetscFunctionReturn(0); 3934e7931f94SStefano Zampini } 3935e7931f94SStefano Zampini 3936e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3937e7931f94SStefano Zampini 3938e7931f94SStefano Zampini #undef __FUNCT__ 3939e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 394053a05cb3SStefano 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[]) 3941e7931f94SStefano Zampini { 394270cf5478SStefano Zampini Mat local_mat; 3943e7931f94SStefano Zampini IS is_sends_internal; 39449d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 394528143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 39469d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3947e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3948e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3949e7931f94SStefano Zampini const PetscInt* is_indices; 3950e7931f94SStefano Zampini MatType new_local_type; 3951e7931f94SStefano Zampini /* buffers */ 3952e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 395328143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 39549d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3955e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3956e7931f94SStefano Zampini /* MPI */ 395728143c3dSStefano Zampini MPI_Comm comm,comm_n; 395828143c3dSStefano Zampini PetscSubcomm subcomm; 3959e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 396028143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 396128143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 396228143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 396328143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 396428143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3965e7931f94SStefano Zampini PetscErrorCode ierr; 3966e7931f94SStefano Zampini 3967e7931f94SStefano Zampini PetscFunctionBegin; 396828143c3dSStefano Zampini /* TODO: add missing checks */ 396928143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 397028143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 397128143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 397228143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3973e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 397428143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3975e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3976e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3977e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3978e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3979e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 398028143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 398170cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 398270cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 398328143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 398470cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 398570cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 398670cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 398770cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 398870cf5478SStefano Zampini } 3989e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 3990e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 3991e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 3992e7931f94SStefano Zampini if (!is_sends) { 399328143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 3994b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 3995c8587f34SStefano Zampini } else { 3996e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 3997e7931f94SStefano Zampini is_sends_internal = is_sends; 3998c8587f34SStefano Zampini } 3999e7931f94SStefano Zampini 4000e7931f94SStefano Zampini /* get comm */ 4001a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4002e7931f94SStefano Zampini 4003e7931f94SStefano Zampini /* compute number of sends */ 4004e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4005e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4006e7931f94SStefano Zampini 4007e7931f94SStefano Zampini /* compute number of receives */ 4008e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4009785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4010e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4011e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4012e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4013e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4014e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4015e7931f94SStefano Zampini 401628143c3dSStefano Zampini /* restrict comm if requested */ 401728143c3dSStefano Zampini subcomm = 0; 401828143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 401928143c3dSStefano Zampini if (restrict_comm) { 4020779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4021779c1cceSStefano Zampini 402228143c3dSStefano Zampini color = 0; 402353a05cb3SStefano Zampini if (restrict_full) { 402453a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 402553a05cb3SStefano Zampini } else { 402653a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 402753a05cb3SStefano Zampini } 402828143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 402928143c3dSStefano Zampini subcommsize = commsize - subcommsize; 403028143c3dSStefano Zampini /* check if reuse has been requested */ 403128143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 403228143c3dSStefano Zampini if (*mat_n) { 403328143c3dSStefano Zampini PetscMPIInt subcommsize2; 403428143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 403528143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 403628143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 403728143c3dSStefano Zampini } else { 403828143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 403928143c3dSStefano Zampini } 404028143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4041779c1cceSStefano Zampini PetscMPIInt rank; 4042779c1cceSStefano Zampini 4043779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 404428143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 404528143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 404628143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4047306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 404828143c3dSStefano Zampini } 404928143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 405028143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 405128143c3dSStefano Zampini } else { 405228143c3dSStefano Zampini comm_n = comm; 405328143c3dSStefano Zampini } 405428143c3dSStefano Zampini 4055e7931f94SStefano Zampini /* prepare send/receive buffers */ 4056785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4057e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4058785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4059e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 406028143c3dSStefano Zampini if (nis) { 4061854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 406228143c3dSStefano Zampini } 4063e7931f94SStefano Zampini 406428143c3dSStefano Zampini /* Get data from local matrices */ 4065e7931f94SStefano Zampini if (!isdense) { 4066a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4067e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4068e7931f94SStefano Zampini /* 4069e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4070e7931f94SStefano Zampini send_buffer_idxs should contain: 4071e7931f94SStefano Zampini - MatType_PRIVATE type 4072e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4073e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4074e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4075e7931f94SStefano Zampini */ 4076e7931f94SStefano Zampini } else { 4077e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 40783bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4079854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4080e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4081e7931f94SStefano Zampini send_buffer_idxs[1] = i; 40823bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4083e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 40843bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4085e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4086e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4087e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4088e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4089c8587f34SStefano Zampini } 4090c8587f34SStefano Zampini } 4091e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 409228143c3dSStefano Zampini /* additional is (if any) */ 409328143c3dSStefano Zampini if (nis) { 409428143c3dSStefano Zampini PetscMPIInt psum; 409528143c3dSStefano Zampini PetscInt j; 409628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 409728143c3dSStefano Zampini PetscInt plen; 409828143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 409928143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 410028143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 410128143c3dSStefano Zampini } 4102854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 410328143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 410428143c3dSStefano Zampini PetscInt plen; 410528143c3dSStefano Zampini const PetscInt *is_array_idxs; 410628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 410728143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 410828143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 410928143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 411028143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 411128143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 411228143c3dSStefano Zampini } 411328143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 411428143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 411528143c3dSStefano Zampini } 411628143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 411728143c3dSStefano Zampini } 411828143c3dSStefano Zampini 4119e7931f94SStefano Zampini buf_size_idxs = 0; 4120e7931f94SStefano Zampini buf_size_vals = 0; 412128143c3dSStefano Zampini buf_size_idxs_is = 0; 4122e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4123e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4124e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 412528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4126e7931f94SStefano Zampini } 4127785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4128785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 412995ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4130e7931f94SStefano Zampini 4131e7931f94SStefano Zampini /* get new tags for clean communications */ 4132e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4133e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 413428143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4135e7931f94SStefano Zampini 4136e7931f94SStefano Zampini /* allocate for requests */ 4137785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4138785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 413995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4140785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4141785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 414295ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4143e7931f94SStefano Zampini 4144e7931f94SStefano Zampini /* communications */ 4145e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4146e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 414728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4148e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4149e7931f94SStefano Zampini source_dest = onodes[i]; 4150e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4151e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4152e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4153e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 415428143c3dSStefano Zampini if (nis) { 415528143c3dSStefano 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); 415628143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 415728143c3dSStefano Zampini } 4158e7931f94SStefano Zampini } 4159e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4160e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4161e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4162e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 416328143c3dSStefano Zampini if (nis) { 416428143c3dSStefano 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); 416528143c3dSStefano Zampini } 4166e7931f94SStefano Zampini } 4167e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4168e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4169e7931f94SStefano Zampini 4170e7931f94SStefano Zampini /* assemble new l2g map */ 4171e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4172e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 41739d30be91SStefano Zampini new_local_rows = 0; 4174e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 41759d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4176e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4177e7931f94SStefano Zampini } 41789d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4179e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 41809d30be91SStefano Zampini new_local_rows = 0; 4181e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 41829d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 41839d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4184e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4185e7931f94SStefano Zampini } 41869d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 41879d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4188e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4189e7931f94SStefano Zampini 4190e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4191e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4192e7931f94SStefano 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) */ 4193e7931f94SStefano Zampini if (n_recvs) { 419428143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4195e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4196e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4197e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4198e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4199e7931f94SStefano Zampini break; 4200e7931f94SStefano Zampini } 4201e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4202e7931f94SStefano Zampini } 4203e7931f94SStefano Zampini switch (new_local_type_private) { 420428143c3dSStefano Zampini case MATDENSE_PRIVATE: 420528143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4206e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4207e7931f94SStefano Zampini bs = 1; 420828143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 420928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 421028143c3dSStefano Zampini bs = 1; 421128143c3dSStefano Zampini } 4212e7931f94SStefano Zampini break; 4213e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4214e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4215e7931f94SStefano Zampini bs = 1; 4216e7931f94SStefano Zampini break; 4217e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4218e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4219e7931f94SStefano Zampini break; 4220e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4221e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4222e7931f94SStefano Zampini break; 4223e7931f94SStefano Zampini default: 42249d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4225e7931f94SStefano Zampini break; 4226e7931f94SStefano Zampini } 422728143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 422828143c3dSStefano Zampini new_local_type = MATSEQDENSE; 422928143c3dSStefano Zampini bs = 1; 4230e7931f94SStefano Zampini } 4231e7931f94SStefano Zampini 423270cf5478SStefano Zampini /* create MATIS object if needed */ 423370cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4234e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4235e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 423670cf5478SStefano Zampini } else { 423770cf5478SStefano Zampini /* it also destroys the local matrices */ 423870cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 423970cf5478SStefano Zampini } 424070cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4241e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 42429d30be91SStefano Zampini 42439d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 42449d30be91SStefano Zampini 42459d30be91SStefano Zampini /* Global to local map of received indices */ 42469d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 42479d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 42489d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 42499d30be91SStefano Zampini 42509d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 42519d30be91SStefano Zampini buf_size_idxs = 0; 42529d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 42539d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 42549d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 42559d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 42569d30be91SStefano Zampini } 42579d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 42589d30be91SStefano Zampini 42599d30be91SStefano Zampini /* set preallocation */ 42609d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 42619d30be91SStefano Zampini if (!newisdense) { 42629d30be91SStefano Zampini PetscInt *new_local_nnz=0; 42639d30be91SStefano Zampini 42649d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 42659d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 42669d30be91SStefano Zampini if (n_recvs) { 42679d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 42689d30be91SStefano Zampini } 42699d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 42709d30be91SStefano Zampini PetscInt j; 42719d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 42729d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 42739d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 42749d30be91SStefano Zampini } 42759d30be91SStefano Zampini } else { 42769d30be91SStefano Zampini /* TODO */ 42779d30be91SStefano Zampini } 42789d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 42799d30be91SStefano Zampini } 42809d30be91SStefano Zampini if (new_local_nnz) { 42819d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 42829d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 42839d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 42849d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 42859d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 42869d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 42879d30be91SStefano Zampini } else { 42889d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 42899d30be91SStefano Zampini } 42909d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 42919d30be91SStefano Zampini } else { 42929d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 42939d30be91SStefano Zampini } 4294e7931f94SStefano Zampini 4295e7931f94SStefano Zampini /* set values */ 4296e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 42979d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 4298e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4299e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 4300e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 43019d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 4302e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4303e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4304e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 430528143c3dSStefano Zampini } else { 430628143c3dSStefano Zampini /* TODO */ 4307e7931f94SStefano Zampini } 4308e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4309e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 4310e7931f94SStefano Zampini } 4311e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4312e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 431370cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 431470cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43159d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 43169d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 4317e7931f94SStefano Zampini 4318dfd14d43SStefano Zampini #if 0 431928143c3dSStefano Zampini if (!restrict_comm) { /* check */ 4320e7931f94SStefano Zampini Vec lvec,rvec; 4321e7931f94SStefano Zampini PetscReal infty_error; 4322e7931f94SStefano Zampini 43232a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 4324e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 4325e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 4326e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 432770cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 4328e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4329e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 4330e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 4331e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 4332e7931f94SStefano Zampini } 433328143c3dSStefano Zampini #endif 4334e7931f94SStefano Zampini 433528143c3dSStefano Zampini /* assemble new additional is (if any) */ 433628143c3dSStefano Zampini if (nis) { 433728143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 433828143c3dSStefano Zampini 433928143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4340854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 434128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 434228143c3dSStefano Zampini psum = 0; 434328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 434428143c3dSStefano Zampini for (j=0;j<nis;j++) { 434528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 434628143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 434728143c3dSStefano Zampini psum += plen; 434828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 434928143c3dSStefano Zampini } 435028143c3dSStefano Zampini } 4351854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 4352854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 435328143c3dSStefano Zampini for (i=1;i<nis;i++) { 435428143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 435528143c3dSStefano Zampini } 435628143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 435728143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 435828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 435928143c3dSStefano Zampini for (j=0;j<nis;j++) { 436028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 436128143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 436228143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 436328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 436428143c3dSStefano Zampini } 436528143c3dSStefano Zampini } 436628143c3dSStefano Zampini for (i=0;i<nis;i++) { 436728143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 436828143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 436928143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 437028143c3dSStefano Zampini } 437128143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 437228143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 437328143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 437428143c3dSStefano Zampini } 4375e7931f94SStefano Zampini /* free workspace */ 437628143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4377e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4378e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4379e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4380e7931f94SStefano Zampini if (isdense) { 4381e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4382e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4383e7931f94SStefano Zampini } else { 4384e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4385e7931f94SStefano Zampini } 438628143c3dSStefano Zampini if (nis) { 438728143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 438828143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 438928143c3dSStefano Zampini } 4390e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4391e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 439228143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4393e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4394e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 439528143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4396e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4397e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4398e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4399e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4400e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 440128143c3dSStefano Zampini if (nis) { 440228143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 440328143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 440428143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 440528143c3dSStefano Zampini } 440628143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 440728143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 440828143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 440928143c3dSStefano Zampini for (i=0;i<nis;i++) { 441028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 441128143c3dSStefano Zampini } 441253a05cb3SStefano Zampini *mat_n = NULL; 441328143c3dSStefano Zampini } 4414e7931f94SStefano Zampini PetscFunctionReturn(0); 4415e7931f94SStefano Zampini } 4416a57a6d2fSStefano Zampini 441712edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4418af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 441912edc857SStefano Zampini 4420c8587f34SStefano Zampini #undef __FUNCT__ 4421c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4422c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4423c8587f34SStefano Zampini { 4424c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4425c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 442620a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 44279881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 442820a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 44296e683305SStefano Zampini IS coarse_is,*isarray; 44306e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 44316e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 4432f9eb5b7dSStefano Zampini PC pc_temp; 4433c8587f34SStefano Zampini PCType coarse_pc_type; 4434c8587f34SStefano Zampini KSPType coarse_ksp_type; 4435f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 44364f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 44376e683305SStefano Zampini Mat t_coarse_mat_is; 44386e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 44396e683305SStefano Zampini PetscMPIInt all_procs; 444074e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 444168457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 444222bc73bbSStefano Zampini PetscScalar *array; 44439881197aSStefano Zampini PetscErrorCode ierr; 4444fdc09c96SStefano Zampini 4445c8587f34SStefano Zampini PetscFunctionBegin; 4446c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 444768457ee5SStefano 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 */ 4448fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 44495a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4450fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4451f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4452f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4453f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4454fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 445551bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 445651bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4457dc4bcba2SStefano Zampini PC pc; 4458dc4bcba2SStefano Zampini PetscBool isbddc; 4459dc4bcba2SStefano Zampini 4460dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4461dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4462dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4463dc4bcba2SStefano Zampini if (isbddc) { 4464dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4465dc4bcba2SStefano Zampini } 4466727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4467fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4468fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4469fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4470f4ddd8eeSStefano Zampini } 4471fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4472fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4473f4ddd8eeSStefano Zampini } 447470cf5478SStefano Zampini /* reset any subassembling information */ 447570cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 44766e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 44776e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4478fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4479f4ddd8eeSStefano Zampini } 4480c8587f34SStefano Zampini 44816e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 44822b510759SStefano Zampini im_active = !!(pcis->n); 44832b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 44846e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 44856e683305SStefano Zampini void_procs = all_procs-active_procs; 44866e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 448774e2c79eSStefano Zampini redist = PETSC_FALSE; 448822bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 44896e683305SStefano Zampini csin_ml = PETSC_TRUE; 44906e683305SStefano Zampini ncoarse_ml = void_procs; 4491779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4492779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 44936e683305SStefano Zampini csin_ds = PETSC_TRUE; 449418a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 449518a45a71SStefano Zampini redist = PETSC_TRUE; 449618a45a71SStefano Zampini } else { 44976e683305SStefano Zampini csin_ds = PETSC_TRUE; 4498779c1cceSStefano Zampini ncoarse_ds = active_procs; 4499779c1cceSStefano Zampini redist = PETSC_TRUE; 450018a45a71SStefano Zampini } 45016e683305SStefano Zampini } else { 45026e683305SStefano Zampini csin_ml = PETSC_FALSE; 45036e683305SStefano Zampini ncoarse_ml = all_procs; 45046e683305SStefano Zampini if (void_procs) { 45056e683305SStefano Zampini csin_ds = PETSC_TRUE; 45066e683305SStefano Zampini ncoarse_ds = void_procs; 45076e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 45086e683305SStefano Zampini } else { 4509779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 451074e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 451174e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 451274e2c79eSStefano Zampini redist = PETSC_TRUE; 451374e2c79eSStefano Zampini } else { 45146e683305SStefano Zampini csin_ds = PETSC_FALSE; 45156e683305SStefano Zampini ncoarse_ds = all_procs; 45166e683305SStefano Zampini } 45176e683305SStefano Zampini } 451874e2c79eSStefano Zampini } 45196e683305SStefano Zampini 45206e683305SStefano Zampini /* 45216e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 45226e683305SStefano Zampini - we have not exceeded the number of levels requested 45236e683305SStefano Zampini - we can actually subassemble the active processes 45246e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 45256e683305SStefano Zampini */ 45266e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 45276e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 45286e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 45296e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 45306e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4531f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 45322b510759SStefano Zampini } else { 4533f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4534c8587f34SStefano Zampini } 4535c8587f34SStefano Zampini } 45366e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 45376e683305SStefano Zampini if (multilevel_allowed) { 45386e683305SStefano Zampini ncoarse = ncoarse_ml; 45396e683305SStefano Zampini csin = csin_ml; 454058da7f69SStefano Zampini redist = PETSC_FALSE; 45416e683305SStefano Zampini } else { 45426e683305SStefano Zampini ncoarse = ncoarse_ds; 45436e683305SStefano Zampini csin = csin_ds; 45446e683305SStefano Zampini } 4545e7931f94SStefano Zampini 4546abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4547abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4548abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4549abbbba34SStefano Zampini 4550abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 455122bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 455222bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 455322bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 455422bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4555b1ecc7b1SStefano Zampini #if 0 4556b9b85e73SStefano Zampini { 4557b9b85e73SStefano Zampini PetscViewer viewer; 4558b9b85e73SStefano Zampini char filename[256]; 4559b1ecc7b1SStefano Zampini sprintf(filename,"local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4560b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4561b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4562b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 4563b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4564b9b85e73SStefano Zampini } 4565b9b85e73SStefano Zampini #endif 4566e176bc59SStefano 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); 45676e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 45686e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45696e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4570abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4571abbbba34SStefano Zampini 45726e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 45736e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 45746e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 45756e683305SStefano Zampini const PetscInt *idxs; 45766e683305SStefano Zampini ISLocalToGlobalMapping tmap; 45776e683305SStefano Zampini 45786e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 45790be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 45806e683305SStefano Zampini /* allocate space for temporary storage */ 4581854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4582854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 45836e683305SStefano Zampini /* allocate for IS array */ 45846e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 45856e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 45866e683305SStefano Zampini nis = nisdofs + nisneu; 4587854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 45886e683305SStefano Zampini /* dofs splitting */ 45896e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 45906e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 45916e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 45926e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 45936e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 45946e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 45956e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 45966e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 45976e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 45986e683305SStefano Zampini } 45996e683305SStefano Zampini /* neumann boundaries */ 46006e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 46016e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 46026e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 46036e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 46046e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 46056e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 46066e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 46076e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 46086e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 46096e683305SStefano Zampini } 46106e683305SStefano Zampini /* free memory */ 46116e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 46126e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 46136e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 46146e683305SStefano Zampini } else { 46156e683305SStefano Zampini nis = 0; 46166e683305SStefano Zampini nisdofs = 0; 46176e683305SStefano Zampini nisneu = 0; 46186e683305SStefano Zampini isarray = NULL; 46196e683305SStefano Zampini } 46206e683305SStefano Zampini /* destroy no longer needed map */ 46216e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 46226e683305SStefano Zampini 46236e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 46246e683305SStefano Zampini coarse_mat_is = NULL; 46256e683305SStefano Zampini if (csin) { 46266e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 462774e2c79eSStefano Zampini if (redist) { 462874e2c79eSStefano Zampini PetscMPIInt rank; 4629779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 463074e2c79eSStefano Zampini 463174e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 463258da7f69SStefano Zampini spc = active_procs/ncoarse; 463358da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 4634779c1cceSStefano Zampini if (im_active) { 4635779c1cceSStefano Zampini destsize = 1; 463674e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 463774e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 463874e2c79eSStefano Zampini } else { 463974e2c79eSStefano Zampini dest[0] = rank/(spc+1); 464074e2c79eSStefano Zampini } 464174e2c79eSStefano Zampini } else { 4642779c1cceSStefano Zampini destsize = 0; 46436e683305SStefano Zampini } 4644779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4645779c1cceSStefano Zampini } else if (csin_type_simple) { 46466e683305SStefano Zampini PetscMPIInt rank; 46476e683305SStefano Zampini PetscInt issize,isidx; 4648779c1cceSStefano Zampini 46496e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 46506e683305SStefano Zampini if (im_active) { 46516e683305SStefano Zampini issize = 1; 46526e683305SStefano Zampini isidx = (PetscInt)rank; 46536e683305SStefano Zampini } else { 46546e683305SStefano Zampini issize = 0; 46556e683305SStefano Zampini isidx = -1; 46566e683305SStefano Zampini } 46576e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4658779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 4659b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 46606e683305SStefano Zampini } 4661779c1cceSStefano Zampini 4662779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 4663779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 4664779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 4665779c1cceSStefano Zampini PetscInt *coarse_candidates; 4666779c1cceSStefano Zampini const PetscInt* tisindices; 4667779c1cceSStefano Zampini 4668779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 4669779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 4670779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4671779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 4672779c1cceSStefano Zampini if (!coarse_candidates[i]) { 4673779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 4674779c1cceSStefano Zampini } 4675779c1cceSStefano Zampini } 4676779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 4677779c1cceSStefano Zampini 4678779c1cceSStefano Zampini 46796e683305SStefano Zampini if (pcbddc->dbg_flag) { 46806e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 46816e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 46826e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 46836e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 4684779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 46856e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 46866e683305SStefano Zampini } 46876e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 46886e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 46896e683305SStefano Zampini } 46906e683305SStefano Zampini /* shift the pattern on coarse candidates */ 46916e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 46926e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 4693854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 46946e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 46956e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 46966e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 46976e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 46986e683305SStefano Zampini } 46996e683305SStefano Zampini if (pcbddc->dbg_flag) { 47006e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47016e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 47026e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 47036e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47046e683305SStefano Zampini } 4705779c1cceSStefano Zampini } 47066e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 470753a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 470853a05cb3SStefano 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); 470953a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 471053a05cb3SStefano 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); 471153a05cb3SStefano Zampini } 47126e683305SStefano Zampini } else { 47136e683305SStefano Zampini if (pcbddc->dbg_flag) { 47146e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47156e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 47166e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47176e683305SStefano Zampini } 47186e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 47196e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 47206e683305SStefano Zampini } 47216e683305SStefano Zampini 47226e683305SStefano Zampini /* create local to global scatters for coarse problem */ 472368457ee5SStefano Zampini if (compute_vecs) { 47246e683305SStefano Zampini PetscInt lrows; 47256e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 47266e683305SStefano Zampini if (coarse_mat_is) { 47276e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 47286e683305SStefano Zampini } else { 47296e683305SStefano Zampini lrows = 0; 47306e683305SStefano Zampini } 47316e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 47326e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 47336e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 47346e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 47356e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 47366e683305SStefano Zampini } 47376e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 47386e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 4739c8587f34SStefano Zampini 4740f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 4741f9eb5b7dSStefano Zampini if (multilevel_allowed) { 4742f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 4743f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 4744f9eb5b7dSStefano Zampini } else { 4745f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 4746f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 4747c8587f34SStefano Zampini } 4748c8587f34SStefano Zampini 47496e683305SStefano Zampini /* print some info if requested */ 47506e683305SStefano Zampini if (pcbddc->dbg_flag) { 47516e683305SStefano Zampini if (!multilevel_allowed) { 47526e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47536e683305SStefano Zampini if (multilevel_requested) { 47546e683305SStefano 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); 47556e683305SStefano Zampini } else if (pcbddc->max_levels) { 47566e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 47576e683305SStefano Zampini } 47586e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47596e683305SStefano Zampini } 47606e683305SStefano Zampini } 47616e683305SStefano Zampini 4762f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 47636e683305SStefano Zampini if (coarse_mat_is) { 47646e683305SStefano Zampini MatReuse coarse_mat_reuse; 47656a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 47666e683305SStefano Zampini if (pcbddc->dbg_flag) { 47676e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 47686e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 47696e683305SStefano Zampini } 4770f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 4771312be037SStefano Zampini char prefix[256],str_level[16]; 4772e604994aSStefano Zampini size_t len; 47736e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 4774422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 4775c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 4776f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 47775f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 4778c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 47796e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 4780c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4781c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4782e604994aSStefano Zampini /* prefix */ 4783e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 4784e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4785e604994aSStefano Zampini if (!pcbddc->current_level) { 4786e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4787e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 4788c8587f34SStefano Zampini } else { 4789e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4790312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4791312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 479234d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4793312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4794e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 4795e604994aSStefano Zampini } 4796e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 47973e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 47983e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 47993e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 48003e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 4801f9eb5b7dSStefano Zampini /* allow user customization */ 4802f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 48033e3c6dadSStefano Zampini } 48043e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 480551bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 48063e3c6dadSStefano Zampini if (nisdofs) { 48073e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 48083e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 48093e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 48103e3c6dadSStefano Zampini } 48113e3c6dadSStefano Zampini } 48123e3c6dadSStefano Zampini if (nisneu) { 48133e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 48143e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 4815312be037SStefano Zampini } 4816f9eb5b7dSStefano Zampini 4817f9eb5b7dSStefano Zampini /* get some info after set from options */ 4818f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 4819f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 48204f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 48216e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 4822f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4823f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 4824f9eb5b7dSStefano Zampini } 482539f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 48264f3a063dSStefano Zampini if (isredundant) { 48274f3a063dSStefano Zampini KSP inner_ksp; 48284f3a063dSStefano Zampini PC inner_pc; 48294f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 48304f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 48314f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 48324f3a063dSStefano Zampini } 4833f9eb5b7dSStefano Zampini 4834f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 4835fa7f1dd8SStefano Zampini if (coarse_reuse) { 483681d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 4837fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 48386e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 4839fa7f1dd8SStefano Zampini } else { 48406e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 4841fa7f1dd8SStefano Zampini } 4842c8587f34SStefano Zampini if (isbddc || isnn) { 484322bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 484470cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 4845b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 484622b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 48476e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 48486e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 48496e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 48506e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 485122b6e8a2SStefano Zampini } 485270cf5478SStefano Zampini } 485353a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 485470cf5478SStefano Zampini } else { 485522bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 485622bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 485722bc73bbSStefano Zampini } 485822bc73bbSStefano Zampini } else { 48592e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 4860c8587f34SStefano Zampini } 4861c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 4862c8587f34SStefano Zampini 48633301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 48645a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 48653301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 48663301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 48673301b35fSStefano Zampini } 48683301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 48693301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 48703301b35fSStefano Zampini } 48713301b35fSStefano Zampini if (pc->pmat->spd_set) { 48723301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 48733301b35fSStefano Zampini } 48746e683305SStefano Zampini /* set operators */ 48755f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 48766e683305SStefano Zampini if (pcbddc->dbg_flag) { 48776e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 48786e683305SStefano Zampini } 48796e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 48806e683305SStefano Zampini coarse_mat = 0; 48816e683305SStefano Zampini } 48826e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 4883b1ecc7b1SStefano Zampini #if 0 4884b9b85e73SStefano Zampini { 4885b9b85e73SStefano Zampini PetscViewer viewer; 4886b9b85e73SStefano Zampini char filename[256]; 4887b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 4888b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 4889b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4890b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 4891b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4892b9b85e73SStefano Zampini } 4893b9b85e73SStefano Zampini #endif 4894c8587f34SStefano Zampini 4895c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 4896298c0119SStefano Zampini #if 0 4897c8587f34SStefano Zampini if (pcbddc->NullSpace) { 4898c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 489998a51de6SStefano Zampini } 4900298c0119SStefano Zampini #endif 4901*b0f5fe93SStefano Zampini /* hack */ 490298a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 490398a51de6SStefano Zampini Vec crhs,csol; 490404708bb6SStefano Zampini 4905f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4906f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 4907f347579bSStefano Zampini if (!csol) { 49082a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4909f9eb5b7dSStefano Zampini } 4910f347579bSStefano Zampini if (!crhs) { 49112a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4912f347579bSStefano Zampini } 4913*b0f5fe93SStefano Zampini } 4914*b0f5fe93SStefano Zampini 4915*b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 4916*b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 4917*b0f5fe93SStefano Zampini 4918*b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 4919*b0f5fe93SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-1,1.0,INSERT_VALUES);CHKERRQ(ierr); 4920*b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 4921*b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 4922*b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4923*b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4924*b0f5fe93SStefano Zampini if (coarse_mat) { 4925*b0f5fe93SStefano Zampini Vec nullv; 4926*b0f5fe93SStefano Zampini PetscScalar *array,*array2; 4927*b0f5fe93SStefano Zampini PetscInt nl; 4928*b0f5fe93SStefano Zampini 4929*b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 4930*b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 4931*b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 4932*b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 4933*b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 4934*b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 4935*b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 4936*b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 4937*b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 4938*b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 4939*b0f5fe93SStefano Zampini } 4940*b0f5fe93SStefano Zampini } 4941*b0f5fe93SStefano Zampini 4942*b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 4943*b0f5fe93SStefano Zampini PetscBool ispreonly; 4944*b0f5fe93SStefano Zampini 4945*b0f5fe93SStefano Zampini if (CoarseNullSpace) { 4946*b0f5fe93SStefano Zampini PetscBool isnull; 4947*b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 4948*b0f5fe93SStefano Zampini if (isnull) { 4949*b0f5fe93SStefano Zampini if (isbddc) { 4950*b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4951*b0f5fe93SStefano Zampini } else { 4952*b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 4953*b0f5fe93SStefano Zampini } 4954*b0f5fe93SStefano Zampini } else { 4955*b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4956*b0f5fe93SStefano Zampini } 4957*b0f5fe93SStefano Zampini } 4958*b0f5fe93SStefano Zampini /* setup coarse ksp */ 4959*b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4960cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4961cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 49626e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4963c8587f34SStefano Zampini KSP check_ksp; 49642b510759SStefano Zampini KSPType check_ksp_type; 4965c8587f34SStefano Zampini PC check_pc; 49666e683305SStefano Zampini Vec check_vec,coarse_vec; 49676a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 49682b510759SStefano Zampini PetscInt its; 49696e683305SStefano Zampini PetscBool compute_eigs; 49706e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 49716e683305SStefano Zampini PetscInt neigs; 49728e185a42SStefano Zampini const char *prefix; 4973c8587f34SStefano Zampini 49742b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 49756e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 4976422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 497723ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4978f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 49792b510759SStefano Zampini if (ispreonly) { 49802b510759SStefano Zampini check_ksp_type = KSPPREONLY; 49816e683305SStefano Zampini compute_eigs = PETSC_FALSE; 49822b510759SStefano Zampini } else { 4983cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 49846e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4985c8587f34SStefano Zampini } 4986c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 49876e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 49886e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 49896e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 4990a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 4991a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 4992a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 4993a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 4994c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4995c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4996c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4997c8587f34SStefano Zampini /* create random vec */ 49986e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 49996e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5000c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5001c8587f34SStefano Zampini if (CoarseNullSpace) { 5002c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5003c8587f34SStefano Zampini } 50046e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5005c8587f34SStefano Zampini /* solve coarse problem */ 50066e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5007c8587f34SStefano Zampini if (CoarseNullSpace) { 50086e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5009c8587f34SStefano Zampini } 5010cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 50116e683305SStefano Zampini if (compute_eigs) { 5012854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5013854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 50146e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 50156e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 50166e683305SStefano Zampini lambda_min = eigs_r[0]; 50176e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 50186e683305SStefano Zampini if (lambda_max>lambda_min) { 5019cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5020cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5021cbcc2c2aSStefano Zampini } 5022c8587f34SStefano Zampini } 5023c8587f34SStefano Zampini } 5024cbcc2c2aSStefano Zampini 5025c8587f34SStefano Zampini /* check coarse problem residual error */ 50266e683305SStefano Zampini if (pcbddc->dbg_flag) { 50276e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 50286e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 50296e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5030c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 50316e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 50326e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5033c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5034779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 50356e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 50366e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 50376e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 50386e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5039*b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5040*b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5041*b0f5fe93SStefano Zampini } 50426e683305SStefano Zampini if (compute_eigs) { 50436e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5044deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5045c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 50466e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 50476e683305SStefano 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); 50486e683305SStefano Zampini for (i=0;i<neigs;i++) { 50496e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5050c8587f34SStefano Zampini } 50516e683305SStefano Zampini } 50526e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 50536e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 50546e683305SStefano Zampini } 5055c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 50566e683305SStefano Zampini if (compute_eigs) { 50576e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 50586e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5059c8587f34SStefano Zampini } 50606e683305SStefano Zampini } 50616e683305SStefano Zampini } 5062cbcc2c2aSStefano Zampini /* print additional info */ 5063cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 50646e683305SStefano Zampini /* waits until all processes reaches this point */ 50656e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5066cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5067cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5068cbcc2c2aSStefano Zampini } 5069cbcc2c2aSStefano Zampini 50702b510759SStefano Zampini /* free memory */ 5071c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5072fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5073c8587f34SStefano Zampini PetscFunctionReturn(0); 5074c8587f34SStefano Zampini } 5075674ae819SStefano Zampini 5076f34684f1SStefano Zampini #undef __FUNCT__ 5077f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5078f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5079f34684f1SStefano Zampini { 5080f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5081f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5082f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5083dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5084dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 508573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5086dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5087f34684f1SStefano Zampini PetscErrorCode ierr; 5088f34684f1SStefano Zampini 5089f34684f1SStefano Zampini PetscFunctionBegin; 5090f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 50910e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 50920e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5093727cdba6SStefano Zampini } 5094dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 50953bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5096dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5097dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5098dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5099dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5100dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5101dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 51020e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 51030e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 51040e6343abSStefano Zampini } 5105dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5106dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5107dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5108dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5109dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5110f34684f1SStefano Zampini 5111f34684f1SStefano Zampini /* check numbering */ 5112f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5113019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5114dc456d91SStefano Zampini PetscInt i; 5115b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5116f34684f1SStefano Zampini 5117f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5118f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5119f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 51200fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 5121019a44ceSStefano Zampini /* counter */ 5122019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5123019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5124019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5125019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5126019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5127019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5128019a44ceSStefano Zampini 5129f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5130f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5131727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5132f34684f1SStefano Zampini } 5133f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5134f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5135f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5136e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5137e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5138e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5139e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5140f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5141019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5142f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5143019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 5144019a44ceSStefano Zampini PetscInt owned = (PetscInt)(array[i]); 5145019a44ceSStefano Zampini PetscInt neigh = (PetscInt)(array2[i]); 5146b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5147019a44ceSStefano 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); 5148f34684f1SStefano Zampini } 5149f34684f1SStefano Zampini } 5150019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5151b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5152f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5153f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5154f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5155f34684f1SStefano Zampini } 5156f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5157f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5158e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5159e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5160f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5161f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5162b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5163ca8b9ea9SStefano Zampini PetscInt *gidxs; 5164ca8b9ea9SStefano Zampini 5165ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 51663bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5167f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5168f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5169f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5170f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 51714bc2dc4bSStefano 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); 5172f34684f1SStefano Zampini } 5173f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5174ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5175f34684f1SStefano Zampini } 5176f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5177302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5178f34684f1SStefano Zampini } 51798bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5180f34684f1SStefano Zampini /* get back data */ 5181f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5182f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5183674ae819SStefano Zampini PetscFunctionReturn(0); 5184674ae819SStefano Zampini } 5185674ae819SStefano Zampini 5186e456f2a8SStefano Zampini #undef __FUNCT__ 5187e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5188a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5189e456f2a8SStefano Zampini { 5190e456f2a8SStefano Zampini IS localis_t; 5191a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5192e456f2a8SStefano Zampini PetscScalar *vals; 5193e456f2a8SStefano Zampini PetscErrorCode ierr; 5194e456f2a8SStefano Zampini 5195e456f2a8SStefano Zampini PetscFunctionBegin; 5196a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5197e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5198854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5199e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5200e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5201a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5202a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 52031035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5204a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 52051035eff8SStefano Zampini } 5206a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5207e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5208e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5209a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5210a7dc3881SStefano Zampini /* now compute set in local ordering */ 5211a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5212a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5213a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5214a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5215a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5216ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5217e456f2a8SStefano Zampini lsize++; 5218e456f2a8SStefano Zampini } 5219e456f2a8SStefano Zampini } 5220854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5221a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5222ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5223e456f2a8SStefano Zampini idxs[lsize++] = i; 5224e456f2a8SStefano Zampini } 5225e456f2a8SStefano Zampini } 5226a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5227a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5228e456f2a8SStefano Zampini *localis = localis_t; 5229e456f2a8SStefano Zampini PetscFunctionReturn(0); 5230e456f2a8SStefano Zampini } 5231906d46d4SStefano Zampini 5232906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5233906d46d4SStefano Zampini #undef __FUNCT__ 5234906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5235906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5236906d46d4SStefano Zampini { 5237906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5238906d46d4SStefano Zampini PetscErrorCode ierr; 5239906d46d4SStefano Zampini 5240906d46d4SStefano Zampini PetscFunctionBegin; 5241906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5242906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5243906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5244906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5245906d46d4SStefano Zampini PetscFunctionReturn(0); 5246906d46d4SStefano Zampini } 5247906d46d4SStefano Zampini 5248906d46d4SStefano Zampini #undef __FUNCT__ 5249906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5250906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5251906d46d4SStefano Zampini { 5252906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5253906d46d4SStefano Zampini PetscErrorCode ierr; 5254906d46d4SStefano Zampini 5255906d46d4SStefano Zampini PetscFunctionBegin; 5256906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5257906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5258906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5259906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5260906d46d4SStefano Zampini PetscFunctionReturn(0); 5261906d46d4SStefano Zampini } 5262b96c3477SStefano Zampini 5263b96c3477SStefano Zampini #undef __FUNCT__ 5264b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 526508122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5266b96c3477SStefano Zampini { 5267a64f4aa4SStefano 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; 5270a64f4aa4SStefano Zampini Mat S_j; 5271b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 5272b96c3477SStefano Zampini PetscBool free_used_adj; 5273b96c3477SStefano Zampini PetscErrorCode ierr; 5274b96c3477SStefano Zampini 5275b96c3477SStefano Zampini PetscFunctionBegin; 5276b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 5277b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 527808122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 5279b96c3477SStefano Zampini used_xadj = NULL; 5280b96c3477SStefano Zampini used_adjncy = NULL; 5281b96c3477SStefano Zampini } else { 528208122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 528308122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 528408122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 528508122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 5286b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 5287b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 5288b96c3477SStefano Zampini } else { 52892fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 5290b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 5291b96c3477SStefano Zampini PetscInt nvtxs; 5292b96c3477SStefano Zampini 52932fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 52942fffb893SStefano Zampini if (flg_row) { 5295b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 5296b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 5297b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 5298b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 52992fffb893SStefano Zampini } else { 53002fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 53012fffb893SStefano Zampini used_xadj = NULL; 53022fffb893SStefano Zampini used_adjncy = NULL; 53032fffb893SStefano Zampini } 53042fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 5305b96c3477SStefano Zampini } 5306b96c3477SStefano Zampini } 5307d5574798SStefano Zampini 5308d5574798SStefano Zampini /* setup sub_schurs data */ 5309a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5310a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 5311a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 5312a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 531306a4e24aSStefano 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); 5314a64f4aa4SStefano Zampini } else { 53156816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 531604708bb6SStefano Zampini PetscBool isseqaij; 53175feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 53185feab87aSStefano Zampini PetscInt n_vertices; 53195feab87aSStefano Zampini 53205feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 53212034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 53225feab87aSStefano Zampini } 532304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 532404708bb6SStefano Zampini if (!isseqaij) { 532504708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 532604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 532704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 532804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 532904708bb6SStefano Zampini } else { 533004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 533104708bb6SStefano Zampini } 533204708bb6SStefano Zampini } 533306a4e24aSStefano 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); 5334a64f4aa4SStefano Zampini } 5335a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5336b96c3477SStefano Zampini 5337b96c3477SStefano Zampini /* free adjacency */ 5338b96c3477SStefano Zampini if (free_used_adj) { 5339b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 5340b96c3477SStefano Zampini } 5341b96c3477SStefano Zampini PetscFunctionReturn(0); 5342b96c3477SStefano Zampini } 5343b96c3477SStefano Zampini 5344b96c3477SStefano Zampini #undef __FUNCT__ 5345b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 534608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 5347b96c3477SStefano Zampini { 5348b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5349b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5350b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5351b96c3477SStefano Zampini PCBDDCGraph graph; 5352b96c3477SStefano Zampini PetscErrorCode ierr; 5353b96c3477SStefano Zampini 5354b96c3477SStefano Zampini PetscFunctionBegin; 5355b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 535608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 53573301b35fSStefano Zampini IS verticesIS,verticescomm; 53583301b35fSStefano Zampini PetscInt vsize,*idxs; 5359b96c3477SStefano Zampini 5360b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 53613301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 53623301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 53633301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 53643301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 53653301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 5366b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 53677fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 53683301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 53693301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 5370b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5371b96c3477SStefano Zampini /* 5372b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 5373b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5374b96c3477SStefano Zampini } 5375b96c3477SStefano Zampini */ 5376b96c3477SStefano Zampini } else { 5377b96c3477SStefano Zampini graph = pcbddc->mat_graph; 5378b96c3477SStefano Zampini } 5379b96c3477SStefano Zampini 5380b96c3477SStefano Zampini /* sub_schurs init */ 5381a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 5382a64f4aa4SStefano Zampini 5383b96c3477SStefano Zampini /* free graph struct */ 538408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 5385b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 5386b96c3477SStefano Zampini } 5387b96c3477SStefano Zampini PetscFunctionReturn(0); 5388b96c3477SStefano Zampini } 5389fa34dd3eSStefano Zampini 5390fa34dd3eSStefano Zampini #undef __FUNCT__ 5391fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 5392fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 5393fa34dd3eSStefano Zampini { 5394fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5395fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5396fa34dd3eSStefano Zampini PetscErrorCode ierr; 5397fa34dd3eSStefano Zampini 5398fa34dd3eSStefano Zampini PetscFunctionBegin; 5399fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 5400fa34dd3eSStefano Zampini IS zerodiag = NULL; 5401fa34dd3eSStefano Zampini Mat S_j,B0=NULL,B0_B=NULL; 5402fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 5403fa34dd3eSStefano Zampini PetscScalar norm,p0_check,*array,*array2; 5404fa34dd3eSStefano Zampini PetscInt i; 5405fa34dd3eSStefano Zampini 5406fa34dd3eSStefano Zampini /* B0 and B0_B */ 5407fa34dd3eSStefano Zampini if (zerodiag) { 5408fa34dd3eSStefano Zampini IS dummy; 5409fa34dd3eSStefano Zampini PetscInt ii[2]; 5410fa34dd3eSStefano Zampini 5411fa34dd3eSStefano Zampini ii[0] = 0; 5412fa34dd3eSStefano Zampini ii[1] = pcbddc->B0_ncol; 5413fa34dd3eSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,1,pcis->n,ii,pcbddc->B0_cols,pcbddc->B0_vals,&B0);CHKERRQ(ierr); 5414fa34dd3eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&dummy);CHKERRQ(ierr); 5415fa34dd3eSStefano Zampini ierr = MatGetSubMatrix(B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 5416fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 5417fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 5418fa34dd3eSStefano Zampini } 5419fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 5420fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 5421fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 5422fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5423fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5424fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5425fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5426fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 5427fa34dd3eSStefano Zampini /* S_j */ 5428fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5429fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 5430fa34dd3eSStefano Zampini 5431fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 5432fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 5433fa34dd3eSStefano Zampini /* continuous in primal space */ 5434fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 5435fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5436fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5437fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5438fa34dd3eSStefano Zampini if (zerodiag) { 5439fa34dd3eSStefano Zampini p0_check = array[pcbddc->local_primal_size-1]; 5440fa34dd3eSStefano Zampini } else { 5441fa34dd3eSStefano Zampini p0_check = 0; 5442fa34dd3eSStefano Zampini } 5443fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5444fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5445fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5446fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5447fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5448fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5449fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 5450fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 5451fa34dd3eSStefano Zampini 5452fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 5453fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 5454fa34dd3eSStefano Zampini /* local with Schur */ 5455fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 5456fa34dd3eSStefano Zampini if (zerodiag) { 5457fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 5458fa34dd3eSStefano Zampini array[0] = p0_check; 5459fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5460fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5461fa34dd3eSStefano Zampini } 5462fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 5463fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5464fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5465fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5466fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5467fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 5468fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5469fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5470fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 5471fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5472fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5473fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5474fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5475fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5476fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 5477fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 5478fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5479fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5480fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5481fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5482fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5483fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5484fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 5485fa34dd3eSStefano Zampini if (zerodiag) { 5486fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 5487fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 5488fa34dd3eSStefano Zampini pcbddc->benign_p0 = array[0]; 5489fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5490fa34dd3eSStefano Zampini } else { 5491fa34dd3eSStefano Zampini pcbddc->benign_p0 = 0.; 5492fa34dd3eSStefano Zampini } 5493fa34dd3eSStefano Zampini /* BDDC */ 5494fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 5495fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 5496fa34dd3eSStefano Zampini 5497fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 5498fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 5499fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 5500fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 5501fa34dd3eSStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 5502fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0 error is %1.4e\n",PetscGlobalRank,PetscAbsScalar(pcbddc->benign_p0-p0_check)); 5503fa34dd3eSStefano Zampini } 5504fa34dd3eSStefano Zampini 5505fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 5506fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 5507fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 5508fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5509fa34dd3eSStefano Zampini ierr = MatDestroy(&B0);CHKERRQ(ierr); 5510fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 5511fa34dd3eSStefano Zampini } 5512fa34dd3eSStefano Zampini PetscFunctionReturn(0); 5513fa34dd3eSStefano Zampini } 5514