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); 74*75c01103SStefano Zampini if (pcbddc->benign_p0_gidx >=0 && (PetscInt)PetscRealPart(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; 86b0f5fe93SStefano Zampini PetscInt nz,n; 87b0f5fe93SStefano 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; 142b0f5fe93SStefano 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.; 173b0f5fe93SStefano 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.; 178b0f5fe93SStefano 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); 192b0f5fe93SStefano Zampini } else { /* if nz == 0, destroy local IS */ 193b0f5fe93SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 194339f8db1SStefano Zampini } 195b0f5fe93SStefano Zampini 196b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 197b0f5fe93SStefano Zampini ierr = MatGetLocalSize(pcbddc->benign_original_mat,&n,NULL);CHKERRQ(ierr); 198b0f5fe93SStefano Zampini have_null = PETSC_TRUE; 199b0f5fe93SStefano Zampini if (!zerodiag && n) have_null = PETSC_FALSE; 200b0f5fe93SStefano 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) { 223251694757SStefano Zampini Mat coarse_mat; 2233964fefecSStefano Zampini Vec rhs,sol; 223451694757SStefano Zampini MatNullSpace nullsp; 2235964fefecSStefano Zampini 2236964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2237964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 223851694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 223951694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 224051694757SStefano Zampini if (nullsp) { 224151694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 224251694757SStefano Zampini } 224312edc857SStefano Zampini if (applytranspose) { 2244964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 224512edc857SStefano Zampini } else { 2246964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 224712edc857SStefano Zampini } 224851694757SStefano Zampini if (nullsp) { 224951694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 225051694757SStefano Zampini } 225112edc857SStefano Zampini } 2252674ae819SStefano Zampini 2253674ae819SStefano Zampini /* Local solution on R nodes */ 225480677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 225580677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 22569f00e9b4SStefano Zampini } 2257674ae819SStefano Zampini 22589f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 22599f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 226012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2261674ae819SStefano Zampini 2262674ae819SStefano Zampini /* Sum contributions from two levels */ 2263dc359a40SStefano Zampini if (applytranspose) { 2264dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2265dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2266dc359a40SStefano Zampini } else { 2267674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 22688eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2269dc359a40SStefano Zampini } 2270efc2fbd9SStefano Zampini /* store p0 */ 2271c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 2272efc2fbd9SStefano Zampini PetscScalar *array; 2273efc2fbd9SStefano Zampini 2274efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2275efc2fbd9SStefano Zampini pcbddc->benign_p0 = array[pcbddc->local_primal_size-1]; 2276efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2277efc2fbd9SStefano Zampini } 2278674ae819SStefano Zampini PetscFunctionReturn(0); 2279674ae819SStefano Zampini } 2280674ae819SStefano Zampini 2281674ae819SStefano Zampini #undef __FUNCT__ 2282674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 228312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2284674ae819SStefano Zampini { 2285674ae819SStefano Zampini PetscErrorCode ierr; 2286674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 228758da7f69SStefano Zampini PetscScalar *array; 228812edc857SStefano Zampini Vec from,to; 2289674ae819SStefano Zampini 2290674ae819SStefano Zampini PetscFunctionBegin; 229112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 229212edc857SStefano Zampini from = pcbddc->coarse_vec; 229312edc857SStefano Zampini to = pcbddc->vec1_P; 229412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 229512edc857SStefano Zampini Vec tvec; 229658da7f69SStefano Zampini 229758da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 229858da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 229912edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 230058da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 230158da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 230258da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 230312edc857SStefano Zampini } 230412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 230512edc857SStefano Zampini from = pcbddc->vec1_P; 230612edc857SStefano Zampini to = pcbddc->coarse_vec; 230712edc857SStefano Zampini } 230812edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 2309674ae819SStefano Zampini PetscFunctionReturn(0); 2310674ae819SStefano Zampini } 2311674ae819SStefano Zampini 2312674ae819SStefano Zampini #undef __FUNCT__ 2313674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 231412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 2315674ae819SStefano Zampini { 2316674ae819SStefano Zampini PetscErrorCode ierr; 2317674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 231858da7f69SStefano Zampini PetscScalar *array; 231912edc857SStefano Zampini Vec from,to; 2320674ae819SStefano Zampini 2321674ae819SStefano Zampini PetscFunctionBegin; 232212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 232312edc857SStefano Zampini from = pcbddc->coarse_vec; 232412edc857SStefano Zampini to = pcbddc->vec1_P; 232512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 232612edc857SStefano Zampini from = pcbddc->vec1_P; 232712edc857SStefano Zampini to = pcbddc->coarse_vec; 232812edc857SStefano Zampini } 232912edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 233012edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 233112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 233212edc857SStefano Zampini Vec tvec; 233358da7f69SStefano Zampini 233412edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 233558da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 233658da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 233758da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 233858da7f69SStefano Zampini } 233958da7f69SStefano Zampini } else { 234058da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 234158da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 234212edc857SStefano Zampini } 234312edc857SStefano Zampini } 2344674ae819SStefano Zampini PetscFunctionReturn(0); 2345674ae819SStefano Zampini } 2346674ae819SStefano Zampini 2347984c4197SStefano Zampini /* uncomment for testing purposes */ 2348984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 2349674ae819SStefano Zampini #undef __FUNCT__ 2350674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 2351674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 2352674ae819SStefano Zampini { 2353674ae819SStefano Zampini PetscErrorCode ierr; 2354674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2355674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2356674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2357984c4197SStefano Zampini /* one and zero */ 2358984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 2359984c4197SStefano Zampini /* space to store constraints and their local indices */ 23609162d606SStefano Zampini PetscScalar *constraints_data; 23619162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 23629162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 23639162d606SStefano Zampini PetscInt *constraints_n; 2364984c4197SStefano Zampini /* iterators */ 2365b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 2366984c4197SStefano Zampini /* BLAS integers */ 2367e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2368e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2369c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2370727cdba6SStefano Zampini /* reuse */ 23710e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 23720e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2373984c4197SStefano Zampini /* change of basis */ 2374b3d85658SStefano Zampini PetscBool qr_needed; 23759162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2376984c4197SStefano Zampini /* auxiliary stuff */ 237764efe560SStefano Zampini PetscInt *nnz,*is_indices; 23788a0068c3SStefano Zampini PetscInt ncc; 2379984c4197SStefano Zampini /* some quantities */ 238045a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2381a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2382984c4197SStefano Zampini 2383674ae819SStefano Zampini PetscFunctionBegin; 23848e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 23858e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 23868e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2387088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2388088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 23890e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 23900e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 23910e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 23920e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 23930e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2394088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2395cf5a6209SStefano Zampini 2396cf5a6209SStefano Zampini /* print some info */ 2397cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2398cf5a6209SStefano Zampini IS vertices; 2399cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2400cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2401cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2402cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2403cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2404cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2405cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2406fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2407fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2408cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2409cf5a6209SStefano Zampini } 2410cf5a6209SStefano Zampini 2411cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 24129162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2413cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2414cf5a6209SStefano Zampini const Vec *nearnullvecs; 2415cf5a6209SStefano Zampini Vec *localnearnullsp; 2416cf5a6209SStefano Zampini PetscScalar *array; 2417cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2418cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2419674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2420b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2421674ae819SStefano Zampini PetscScalar *work; 2422674ae819SStefano Zampini PetscReal *singular_vals; 2423674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2424674ae819SStefano Zampini PetscReal *rwork; 2425674ae819SStefano Zampini #endif 2426674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2427674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2428674ae819SStefano Zampini #else 2429964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2430964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2431674ae819SStefano Zampini #endif 2432674ae819SStefano Zampini 2433674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2434d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2435d06fc5fdSStefano Zampini /* free unneeded index sets */ 2436d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2437d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2438674ae819SStefano Zampini } 2439d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2440d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2441d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2442d06fc5fdSStefano Zampini } 2443d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2444d06fc5fdSStefano Zampini n_ISForEdges = 0; 2445d06fc5fdSStefano Zampini } 2446d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2447d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2448d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2449d06fc5fdSStefano Zampini } 2450d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2451d06fc5fdSStefano Zampini n_ISForFaces = 0; 2452d06fc5fdSStefano Zampini } 245370022509SStefano Zampini 245470022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 245570022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 245670022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 245770022509SStefano Zampini if (pcbddc->NullSpace) { 245870022509SStefano Zampini PetscBool tbool[2],gbool[2]; 245970022509SStefano Zampini 246070022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2461b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2462d06fc5fdSStefano Zampini if (!ISForEdges) { 2463d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2464d06fc5fdSStefano Zampini } 2465b8ffe317SStefano Zampini } 2466d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2467d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2468d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2469d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2470d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 247198a51de6SStefano Zampini } 247270022509SStefano Zampini #endif 247308122e43SStefano Zampini 2474674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2475674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2476674ae819SStefano Zampini if (nearnullsp) { 2477674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2478f4ddd8eeSStefano Zampini /* remove any stored info */ 2479f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2480f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2481f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2482f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2483f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2484473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2485f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2486f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2487f4ddd8eeSStefano Zampini } 2488984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2489984c4197SStefano Zampini nnsp_size = 0; 2490674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2491674ae819SStefano Zampini } 2492984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2493984c4197SStefano Zampini max_constraints = nnsp_size; 2494984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2495984c4197SStefano Zampini 2496674ae819SStefano Zampini /* 2497674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 24989162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 24999162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 25009162d606SStefano Zampini There can be multiple constraints per connected component 2501674ae819SStefano Zampini */ 2502674ae819SStefano Zampini n_vertices = 0; 2503674ae819SStefano Zampini if (ISForVertices) { 2504674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2505674ae819SStefano Zampini } 25069162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 25079162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 25089162d606SStefano Zampini 25099162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 25109162d606SStefano Zampini total_counts *= max_constraints; 2511674ae819SStefano Zampini total_counts += n_vertices; 25124641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 25139162d606SStefano Zampini 2514674ae819SStefano Zampini total_counts = 0; 2515674ae819SStefano Zampini max_size_of_constraint = 0; 2516674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 25179162d606SStefano Zampini IS used_is; 2518674ae819SStefano Zampini if (i<n_ISForEdges) { 25199162d606SStefano Zampini used_is = ISForEdges[i]; 2520674ae819SStefano Zampini } else { 25219162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2522674ae819SStefano Zampini } 25239162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2524674ae819SStefano Zampini total_counts += j; 2525674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2526674ae819SStefano Zampini } 25279162d606SStefano 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); 25289162d606SStefano Zampini 2529984c4197SStefano Zampini /* get local part of global near null space vectors */ 2530785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2531984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2532984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2533e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2534e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2535984c4197SStefano Zampini } 2536674ae819SStefano Zampini 2537242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2538242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2539a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2540242a89d7SStefano Zampini 2541984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2542a773dcb8SStefano Zampini if (!skip_lapack) { 2543674ae819SStefano Zampini PetscScalar temp_work; 2544911cabfeSStefano Zampini 2545674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2546984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2547785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2548785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2549785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2550674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2551785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2552674ae819SStefano Zampini #endif 2553674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2554c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2555c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2556674ae819SStefano Zampini lwork = -1; 2557674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2558674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2559c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2560674ae819SStefano Zampini #else 2561c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2562674ae819SStefano Zampini #endif 2563674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2564984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2565674ae819SStefano Zampini #else /* on missing GESVD */ 2566674ae819SStefano Zampini /* SVD */ 2567674ae819SStefano Zampini PetscInt max_n,min_n; 2568674ae819SStefano Zampini max_n = max_size_of_constraint; 2569984c4197SStefano Zampini min_n = max_constraints; 2570984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2571674ae819SStefano Zampini min_n = max_size_of_constraint; 2572984c4197SStefano Zampini max_n = max_constraints; 2573674ae819SStefano Zampini } 2574785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2575674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2576785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2577674ae819SStefano Zampini #endif 2578674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2579674ae819SStefano Zampini lwork = -1; 2580e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2581e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2582b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2583674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2584674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 25859162d606SStefano 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)); 2586674ae819SStefano Zampini #else 25879162d606SStefano 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)); 2588674ae819SStefano Zampini #endif 2589674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2590984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2591984c4197SStefano Zampini #endif /* on missing GESVD */ 2592674ae819SStefano Zampini /* Allocate optimal workspace */ 2593674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2594854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2595674ae819SStefano Zampini } 2596674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2597674ae819SStefano Zampini total_counts = 0; 25989162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 25999162d606SStefano Zampini constraints_data_ptr[0] = 0; 2600674ae819SStefano Zampini /* vertices */ 26019162d606SStefano Zampini if (n_vertices) { 2602674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 26039162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2604674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 26059162d606SStefano Zampini constraints_n[total_counts] = 1; 26069162d606SStefano Zampini constraints_data[total_counts] = 1.0; 26079162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 26089162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2609674ae819SStefano Zampini total_counts++; 2610674ae819SStefano Zampini } 2611674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2612674ae819SStefano Zampini n_vertices = total_counts; 2613674ae819SStefano Zampini } 2614984c4197SStefano Zampini 2615674ae819SStefano Zampini /* edges and faces */ 26169162d606SStefano Zampini total_counts_cc = total_counts; 2617911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 26189162d606SStefano Zampini IS used_is; 26199162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 26209162d606SStefano Zampini 2621911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 26229162d606SStefano Zampini used_is = ISForEdges[ncc]; 2623984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2624674ae819SStefano Zampini } else { 26259162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2626984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2627674ae819SStefano Zampini } 2628674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 26299162d606SStefano Zampini 26309162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 26319162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2632984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2633984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2634674ae819SStefano Zampini if (nnsp_has_cnst) { 26355b08dc53SStefano Zampini PetscScalar quad_value; 26369162d606SStefano Zampini 26379162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 26389162d606SStefano Zampini idxs_copied = PETSC_TRUE; 26399162d606SStefano Zampini 2640a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2641674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2642a773dcb8SStefano Zampini } else { 2643a773dcb8SStefano Zampini quad_value = 1.0; 2644a773dcb8SStefano Zampini } 2645674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 26469162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 2647674ae819SStefano Zampini } 26489162d606SStefano Zampini temp_constraints++; 2649674ae819SStefano Zampini total_counts++; 2650674ae819SStefano Zampini } 2651674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2652984c4197SStefano Zampini PetscReal real_value; 26539162d606SStefano Zampini PetscScalar *ptr_to_data; 26549162d606SStefano Zampini 2655984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 26569162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 2657674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 26589162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 2659674ae819SStefano Zampini } 2660984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2661984c4197SStefano Zampini /* check if array is null on the connected component */ 2662e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 26639162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 26645b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2665674ae819SStefano Zampini temp_constraints++; 2666674ae819SStefano Zampini total_counts++; 26679162d606SStefano Zampini if (!idxs_copied) { 26689162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 26699162d606SStefano Zampini idxs_copied = PETSC_TRUE; 2670674ae819SStefano Zampini } 2671674ae819SStefano Zampini } 26729162d606SStefano Zampini } 26739162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 267445a1bb75SStefano Zampini valid_constraints = temp_constraints; 2675eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2676a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 26779162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 26789162d606SStefano Zampini 26799162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2680a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 26819162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 2682a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 26839162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 2684a773dcb8SStefano Zampini } else { /* perform SVD */ 2685984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 26869162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2687674ae819SStefano Zampini 2688674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2689984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 2690984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 2691984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 2692984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 2693984c4197SStefano Zampini from that computed using LAPACKgesvd 2694984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 2695984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 2696984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 2697674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 2698e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2699984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2700674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 2701674ae819SStefano Zampini for (k=0;k<j+1;k++) { 27029162d606SStefano 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)); 2703674ae819SStefano Zampini } 2704674ae819SStefano Zampini } 2705e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 2706e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2707e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 2708674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2709c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 2710674ae819SStefano Zampini #else 2711c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 2712674ae819SStefano Zampini #endif 2713674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2714984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 2715984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 2716674ae819SStefano Zampini j = 0; 2717984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 2718674ae819SStefano Zampini total_counts = total_counts-j; 271945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 2720e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 2721c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2722c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2723c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 2724c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2725c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 2726c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2727674ae819SStefano Zampini if (j<temp_constraints) { 2728984c4197SStefano Zampini PetscInt ii; 2729984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 2730674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27319162d606SStefano 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)); 2732674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2733984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 2734674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 27359162d606SStefano 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]; 2736674ae819SStefano Zampini } 2737674ae819SStefano Zampini } 2738674ae819SStefano Zampini } 2739674ae819SStefano Zampini #else /* on missing GESVD */ 2740e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2741e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2742b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2743674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2744674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 27459162d606SStefano 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)); 2746674ae819SStefano Zampini #else 27479162d606SStefano 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)); 2748674ae819SStefano Zampini #endif 2749984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 2750674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2751984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 2752e310c8b4SStefano Zampini k = temp_constraints; 2753e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 2754674ae819SStefano Zampini j = 0; 2755e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 275645a1bb75SStefano Zampini valid_constraints = k-j; 2757911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 2758984c4197SStefano Zampini #endif /* on missing GESVD */ 2759674ae819SStefano Zampini } 2760a773dcb8SStefano Zampini } 27619162d606SStefano Zampini /* update pointers information */ 27629162d606SStefano Zampini if (valid_constraints) { 27639162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 27649162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 27659162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 27669162d606SStefano Zampini /* set change_of_basis flag */ 276745a1bb75SStefano Zampini if (boolforchange) { 2768b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 27699162d606SStefano Zampini } 2770b3d85658SStefano Zampini total_counts_cc++; 277145a1bb75SStefano Zampini } 277245a1bb75SStefano Zampini } 2773984c4197SStefano Zampini /* free workspace */ 27748f1c130eSStefano Zampini if (!skip_lapack) { 2775984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2776984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2777984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 2778984c4197SStefano Zampini #endif 2779984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 2780984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2781984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 2782984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 2783984c4197SStefano Zampini #endif 2784984c4197SStefano Zampini } 2785984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2786984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 2787984c4197SStefano Zampini } 2788984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 2789cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 2790cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2791cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2792cf5a6209SStefano Zampini } 2793cf5a6209SStefano Zampini if (n_ISForFaces) { 2794cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2795cf5a6209SStefano Zampini } 2796cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2797cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2798cf5a6209SStefano Zampini } 2799cf5a6209SStefano Zampini if (n_ISForEdges) { 2800cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2801cf5a6209SStefano Zampini } 2802cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 280308122e43SStefano Zampini } else { 280408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2805984c4197SStefano Zampini 280608122e43SStefano Zampini total_counts = 0; 280708122e43SStefano Zampini n_vertices = 0; 2808d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 2809d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 281008122e43SStefano Zampini } 281108122e43SStefano Zampini max_constraints = 0; 28129162d606SStefano Zampini total_counts_cc = 0; 281308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 281408122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 28159162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 281608122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 281708122e43SStefano Zampini } 28189162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 28199162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 28209162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 28219162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 282274d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 28239162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 28249162d606SStefano Zampini total_counts_cc = 0; 28259162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 28269162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 28279162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 282808122e43SStefano Zampini } 282908122e43SStefano Zampini } 28309162d606SStefano Zampini #if 0 28319162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 28329162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 28339162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 28349162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 28359162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 28369162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 28379162d606SStefano Zampini } 28389162d606SStefano Zampini printf("\n"); 28399162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 28409162d606SStefano Zampini } 28411b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 28428bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 28431b968477SStefano Zampini } 28441b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 28458bec7fa6SStefano 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]); 28461b968477SStefano Zampini } 284708122e43SStefano Zampini #endif 284808122e43SStefano Zampini 28498bec7fa6SStefano Zampini max_size_of_constraint = 0; 28509162d606SStefano 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]); 28519162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 285208122e43SStefano Zampini /* Change of basis */ 2853b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 285408122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 285508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 285608122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 2857b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 285808122e43SStefano Zampini } 285908122e43SStefano Zampini } 286008122e43SStefano Zampini } 286108122e43SStefano Zampini } 2862984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 2863019a44ceSStefano Zampini /* allocating one extra space (in case an extra primal dof should be stored for the benign trick */ 2864019a44ceSStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+1,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 286508122e43SStefano Zampini 28669162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 28679162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 28689162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 28699162d606SStefano 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); 287008122e43SStefano Zampini } 2871674ae819SStefano Zampini 2872674ae819SStefano Zampini /* Create constraint matrix */ 2873674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 287416f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 2875984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 2876984c4197SStefano Zampini 2877984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 2878a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 2879a717540cSStefano Zampini qr_needed = PETSC_FALSE; 288074d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 2881984c4197SStefano Zampini total_primal_vertices=0; 2882b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 28839162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 28849162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 2885984c4197SStefano Zampini if (size_of_constraint == 1) { 28869162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 2887b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 288864efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 28899162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 28909162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 2891a717540cSStefano Zampini } 2892b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 289374d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 2894a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 2895a717540cSStefano Zampini qr_needed = PETSC_TRUE; 2896a717540cSStefano Zampini } 2897fa434743SStefano Zampini } else { 2898b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 2899fa434743SStefano Zampini } 2900a717540cSStefano Zampini } 2901b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 2902b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 2903674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 290470022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2905b3d85658SStefano Zampini 2906019a44ceSStefano Zampini /* allocating one extra space (in case an extra primal dof should be stored for the benign trick */ 2907019a44ceSStefano 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); 29080e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 29090e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 2910984c4197SStefano Zampini 2911984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 291274d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 2913785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2914984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 291574d5cdf7SStefano Zampini 2916984c4197SStefano Zampini j = total_primal_vertices; 291774d5cdf7SStefano Zampini total_counts = total_primal_vertices; 2918b3d85658SStefano Zampini cum = total_primal_vertices; 29199162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 29204641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2921b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 2922b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 2923b3d85658SStefano Zampini cum++; 29249162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 292574d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 292674d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 292774d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 292874d5cdf7SStefano Zampini } 29299162d606SStefano Zampini j += constraints_n[i]; 2930674ae819SStefano Zampini } 2931674ae819SStefano Zampini } 2932674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2933674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2934088faed8SStefano Zampini 2935674ae819SStefano Zampini /* set values in constraint matrix */ 2936984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 29370e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2938674ae819SStefano Zampini } 2939984c4197SStefano Zampini total_counts = total_primal_vertices; 29409162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 29414641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 29429162d606SStefano Zampini PetscInt *cols; 29439162d606SStefano Zampini 29449162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 29459162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 29469162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 29479162d606SStefano Zampini PetscInt row = total_counts+k; 29489162d606SStefano Zampini PetscScalar *vals; 29499162d606SStefano Zampini 29509162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 29519162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 29529162d606SStefano Zampini } 29539162d606SStefano Zampini total_counts += constraints_n[i]; 2954674ae819SStefano Zampini } 2955674ae819SStefano Zampini } 2956674ae819SStefano Zampini /* assembling */ 2957674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2958674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2959088faed8SStefano Zampini 2960984c4197SStefano Zampini /* 296145a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2962984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2963984c4197SStefano Zampini */ 2964674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2965674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2966026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2967984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2968984c4197SStefano Zampini /* working stuff for GEQRF */ 296981d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2970984c4197SStefano Zampini PetscBLASInt lqr_work; 2971984c4197SStefano Zampini /* working stuff for UNGQR */ 2972984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2973984c4197SStefano Zampini PetscBLASInt lgqr_work; 2974984c4197SStefano Zampini /* working stuff for TRTRS */ 2975984c4197SStefano Zampini PetscScalar *trs_rhs; 29763f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2977984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2978984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2979984c4197SStefano Zampini PetscScalar *start_vals; 2980984c4197SStefano Zampini /* working stuff for values insertion */ 29814641a718SStefano Zampini PetscBT is_primal; 298264efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 2983906d46d4SStefano Zampini /* matrix sizes */ 2984906d46d4SStefano Zampini PetscInt global_size,local_size; 2985906d46d4SStefano Zampini /* temporary change of basis */ 2986906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2987cf5a6209SStefano Zampini /* extra space for debugging */ 2988cf5a6209SStefano Zampini PetscScalar *dbg_work; 2989984c4197SStefano Zampini 2990906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2991906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 299216f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2993bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 2994906d46d4SStefano Zampini /* nonzeros for local mat */ 2995bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 2996bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 29979162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 2998a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 29999162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3000a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 30019162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3002a717540cSStefano Zampini } else { 30039162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 30049162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3005a717540cSStefano Zampini } 3006a717540cSStefano Zampini } 3007a717540cSStefano Zampini } 3008906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3009bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3010a717540cSStefano Zampini /* Set initial identity in the matrix */ 3011bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3012906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3013a717540cSStefano Zampini } 3014a717540cSStefano Zampini 3015a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3016a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3017a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3018a717540cSStefano Zampini } 3019a717540cSStefano Zampini 3020a717540cSStefano Zampini 3021a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3022a717540cSStefano Zampini /* 3023a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3024a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3025a717540cSStefano Zampini 3026a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3027a717540cSStefano Zampini 3028a6b551f4SStefano 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) 3029a6b551f4SStefano Zampini 3030a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3031a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3032a717540cSStefano Zampini | ... | 3033a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3034a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3035a717540cSStefano Zampini 3036a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3037a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3038a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3039a6b551f4SStefano Zampini 3040a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3041a717540cSStefano Zampini */ 3042a717540cSStefano Zampini if (qr_needed) { 3043984c4197SStefano Zampini /* space to store Q */ 3044854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3045984c4197SStefano Zampini /* first we issue queries for optimal work */ 30463f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 30473f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 30483f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3049984c4197SStefano Zampini lqr_work = -1; 30503f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3051984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3052984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3053785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3054984c4197SStefano Zampini lgqr_work = -1; 30553f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 30563f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 30573f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 30583f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 30593f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 30603f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3061984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3062984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3063785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3064984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3065785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3066984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3067785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3068a717540cSStefano Zampini /* allocating workspace for check */ 3069a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3070cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3071a717540cSStefano Zampini } 3072a717540cSStefano Zampini } 3073984c4197SStefano Zampini /* array to store whether a node is primal or not */ 30744641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3075473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 30760e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 307739e2fb2aSStefano Zampini if (i != total_primal_vertices) { 307839e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 30794641a718SStefano Zampini } 308039e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 308139e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 308239e2fb2aSStefano Zampini } 308339e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3084984c4197SStefano Zampini 3085a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 30869162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 30879162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 30884641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3089984c4197SStefano Zampini /* get constraint info */ 30909162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3091984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3092984c4197SStefano Zampini 3093984c4197SStefano Zampini if (pcbddc->dbg_flag) { 30949162d606SStefano 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); 3095674ae819SStefano Zampini } 3096984c4197SStefano Zampini 3097fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3098a717540cSStefano Zampini 3099a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3100a717540cSStefano Zampini if (pcbddc->dbg_flag) { 31019162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3102a717540cSStefano Zampini } 3103984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 31049162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3105984c4197SStefano Zampini 3106984c4197SStefano Zampini /* compute QR decomposition of constraints */ 31073f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 31083f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 31093f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3110674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31113f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3112984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3113674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3114984c4197SStefano Zampini 3115984c4197SStefano Zampini /* explictly compute R^-T */ 3116984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3117984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 31183f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 31193f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 31203f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 31213f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3122984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31233f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3124984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3125984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3126984c4197SStefano Zampini 3127a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 31283f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 31293f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 31303f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 31313f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3132984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31333f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3134984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3135984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3136984c4197SStefano Zampini 3137984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3138984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3139984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 31403f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 31413f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 31423f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 31433f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 31443f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 31453f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3146984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 31479162d606SStefano 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)); 3148984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 31499162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3150984c4197SStefano Zampini 3151984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 31529162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3153984c4197SStefano Zampini /* insert cols for primal dofs */ 3154984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3155984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 31569162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3157906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3158984c4197SStefano Zampini } 3159984c4197SStefano Zampini /* insert cols for dual dofs */ 3160984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 31619162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3162984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 31639162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3164906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3165984c4197SStefano Zampini j++; 3166674ae819SStefano Zampini } 3167674ae819SStefano Zampini } 3168984c4197SStefano Zampini 3169984c4197SStefano Zampini /* check change of basis */ 3170984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3171984c4197SStefano Zampini PetscInt ii,jj; 3172984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3173c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3174c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3175c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3176c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3177c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3178c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3179984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3180cf5a6209SStefano 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)); 3181984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3182984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3183984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3184cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3185cf5a6209SStefano 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; 3186674ae819SStefano Zampini } 3187674ae819SStefano Zampini } 3188984c4197SStefano Zampini if (!valid_qr) { 318922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3190984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3191984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3192cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3193cf5a6209SStefano 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])); 3194674ae819SStefano Zampini } 3195cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3196cf5a6209SStefano 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])); 3197984c4197SStefano Zampini } 3198984c4197SStefano Zampini } 3199984c4197SStefano Zampini } 3200674ae819SStefano Zampini } else { 320122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3202674ae819SStefano Zampini } 3203674ae819SStefano Zampini } 3204a717540cSStefano Zampini } else { /* simple transformation block */ 3205a717540cSStefano Zampini PetscInt row,col; 3206a6b551f4SStefano Zampini PetscScalar val,norm; 3207a6b551f4SStefano Zampini 3208a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 32099162d606SStefano 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)); 3210a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 32119162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 32129162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3213bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 32149162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3215906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 32169162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3217a717540cSStefano Zampini } else { 3218a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 32199162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3220a717540cSStefano Zampini if (row != col) { 32219162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3222a717540cSStefano Zampini } else { 32239162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3224a717540cSStefano Zampini } 3225906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3226a717540cSStefano Zampini } 3227a717540cSStefano Zampini } 3228a717540cSStefano Zampini } 322998a51de6SStefano Zampini if (pcbddc->dbg_flag) { 323022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3231a717540cSStefano Zampini } 3232674ae819SStefano Zampini } 3233984c4197SStefano Zampini } else { 3234984c4197SStefano Zampini if (pcbddc->dbg_flag) { 32359162d606SStefano 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); 3236674ae819SStefano Zampini } 3237674ae819SStefano Zampini } 3238674ae819SStefano Zampini } 3239a717540cSStefano Zampini 3240a717540cSStefano Zampini /* free workspace */ 3241a717540cSStefano Zampini if (qr_needed) { 3242984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3243cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3244984c4197SStefano Zampini } 3245984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3246984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3247984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3248984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3249984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3250674ae819SStefano Zampini } 3251a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3252906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3253906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3254906d46d4SStefano Zampini 3255906d46d4SStefano Zampini /* assembling of global change of variable */ 3256bbb9e6c6SStefano Zampini { 3257bbb9e6c6SStefano Zampini Mat tmat; 325816f15bc4SStefano Zampini PetscInt bs; 325916f15bc4SStefano Zampini 3260906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3261906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3262bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3263bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3264bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3265bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 326616f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 326716f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3268906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3269bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3270bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3271bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3272bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3273bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3274e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3275e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3276bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3277bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3278906d46d4SStefano Zampini } 3279906d46d4SStefano Zampini /* check */ 3280906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3281906d46d4SStefano Zampini PetscReal error; 3282906d46d4SStefano Zampini Vec x,x_change; 3283906d46d4SStefano Zampini 3284906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3285906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3286906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3287906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3288e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3289e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3290bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 3291e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3292e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3293906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 3294906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3295906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3296906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3297bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 3298906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3299906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3300906d46d4SStefano Zampini } 3301b96c3477SStefano Zampini 3302b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 3303b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3304b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 3305b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 3306ac632422SStefano Zampini Mat S_new,tmat; 3307b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 3308b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 3309b087196eSStefano Zampini const PetscScalar *array; 3310b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 3311b087196eSStefano Zampini PetscInt i,n_V; 3312bbb9e6c6SStefano Zampini 3313bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 33146816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 3315b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 3316b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 3317b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 3318b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 3319bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 3320b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 3321ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3322b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 3323ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3324b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3325b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 3326b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3327b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3328b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 3329b087196eSStefano Zampini for (i=0;i<n_V;i++) { 3330b087196eSStefano Zampini PetscScalar val; 3331b087196eSStefano Zampini PetscInt idx; 3332b087196eSStefano Zampini 3333b087196eSStefano Zampini idx = idxs_V[i]; 3334b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 3335b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 3336b087196eSStefano Zampini } 3337b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3338b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3339ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 3340ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3341ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 3342ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3343b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 3344ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3345b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3346ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 3347ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3348ac632422SStefano Zampini } 3349b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 3350b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3351b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3352b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3353b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 3354b96c3477SStefano Zampini } 3355b96c3477SStefano Zampini } 3356906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 3357906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 3358b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3359b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 3360b9b85e73SStefano Zampini } 3361906d46d4SStefano Zampini 3362906d46d4SStefano Zampini /* set up change of basis context */ 3363906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 3364906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 3365906d46d4SStefano Zampini 3366906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 3367906d46d4SStefano Zampini PetscInt global_size,local_size; 3368906d46d4SStefano Zampini 3369906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3370906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3371906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 3372906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3373906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 3374906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 3375906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3376906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3377906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3378906d46d4SStefano Zampini } else { 3379906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3380906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3381906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3382906d46d4SStefano Zampini } 3383906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3384906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3385906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3386906d46d4SStefano Zampini } else { 3387906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3388906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3389906d46d4SStefano Zampini } 3390906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3391906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3392906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3393906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3394b9b85e73SStefano Zampini } 3395a717540cSStefano Zampini 3396019a44ceSStefano Zampini /* add pressure dof to set of primal nodes for numbering purposes */ 3397c9ed8603SStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 3398c9ed8603SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx; 3399d16cbb6bSStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx; 3400019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 3401019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 3402019a44ceSStefano Zampini pcbddc->local_primal_size++; 3403019a44ceSStefano Zampini } 3404019a44ceSStefano Zampini 3405019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 3406727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3407727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 3408aff50787SStefano 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); 3409c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 34100e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 3411aff50787SStefano 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); 3412727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3413727cdba6SStefano Zampini } 34140e6343abSStefano Zampini } 34150e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3416727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3417727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3418727cdba6SStefano Zampini 3419a717540cSStefano Zampini /* flush dbg viewer */ 3420b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3421b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3422b8ffe317SStefano Zampini } 3423a717540cSStefano Zampini 3424e310c8b4SStefano Zampini /* free workspace */ 3425a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 34264641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 342708122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 34289162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 34299162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 343008122e43SStefano Zampini } else { 34319162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 34329162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 34339162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 343408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 343508122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 34369162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 34379162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 343808122e43SStefano Zampini } 3439674ae819SStefano Zampini PetscFunctionReturn(0); 3440674ae819SStefano Zampini } 3441674ae819SStefano Zampini 3442674ae819SStefano Zampini #undef __FUNCT__ 3443674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3444674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3445674ae819SStefano Zampini { 3446674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3447674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3448674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 34497fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3450674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3451674ae819SStefano Zampini 3452674ae819SStefano Zampini PetscFunctionBegin; 34538e61c736SStefano Zampini /* Reset previously computed graph */ 34548e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3455674ae819SStefano Zampini /* Init local Graph struct */ 34567fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 34573bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3458674ae819SStefano Zampini 3459575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 34605099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 34615099eff2SStefano 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); 3462575ad6abSStefano Zampini } 34639577ea80SStefano Zampini 3464674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 34654d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 34664d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 34674d379d7bSStefano Zampini PetscInt nvtxs; 3468e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3469674ae819SStefano Zampini 34704d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 34712fffb893SStefano Zampini 34722fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34732fffb893SStefano Zampini if (flg_row) { 34744d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3475b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 34762fffb893SStefano Zampini } 34772fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 34789b28b941SStefano 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 */ 34794d379d7bSStefano Zampini IS is_dummy; 34804d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 34814d379d7bSStefano Zampini PetscInt j,sum; 34824d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 34834d379d7bSStefano Zampini const PetscInt *idxs; 34844d379d7bSStefano Zampini PCBDDCGraph graph; 34854d379d7bSStefano Zampini PetscBT is_on_boundary; 34864d379d7bSStefano Zampini 34874d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 34884d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 34894d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 34904d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 34917fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 34924d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3493e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3494e496cd5dSStefano Zampini if (flg_row) { 34954d379d7bSStefano Zampini graph->xadj = xadj; 34964d379d7bSStefano Zampini graph->adjncy = adjncy; 3497e496cd5dSStefano Zampini } 34984d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 34994d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3500e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 35014d379d7bSStefano Zampini 35024d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 35039b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 35044d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 35054d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 35064d379d7bSStefano Zampini } 35074d379d7bSStefano Zampini } 35084d379d7bSStefano Zampini 3509e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 35104d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 35114d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 35124d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 35134d379d7bSStefano Zampini } 35144d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 35154d379d7bSStefano Zampini 3516e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 35174d379d7bSStefano Zampini sum = 0; 35184d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 35194d379d7bSStefano Zampini PetscInt sizecc = 0; 35204d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 35214d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 35224d379d7bSStefano Zampini sizecc++; 35234d379d7bSStefano Zampini } 35244d379d7bSStefano Zampini } 35254d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 35264d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 35274d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 35284d379d7bSStefano Zampini } 35294d379d7bSStefano Zampini } 35304d379d7bSStefano Zampini sum += sizecc*sizecc; 35314d379d7bSStefano Zampini } 35324d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 35334d379d7bSStefano Zampini sum = 0; 3534e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 35354d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 35364d379d7bSStefano Zampini cxadj[i] = sum; 35374d379d7bSStefano Zampini sum += temp; 35384d379d7bSStefano Zampini } 3539e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 35404d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 35414d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 35424d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 35434d379d7bSStefano Zampini PetscInt k,sizecc = 0; 35444d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 35454d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 35464d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 35474d379d7bSStefano Zampini sizecc++; 35484d379d7bSStefano Zampini } 35494d379d7bSStefano Zampini } 35504d379d7bSStefano Zampini } 35514d379d7bSStefano Zampini } 35524d379d7bSStefano Zampini } 35539b28b941SStefano Zampini if (sum) { 3554e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 35554d379d7bSStefano Zampini } else { 35564d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 35574d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 35584d379d7bSStefano Zampini } 35594d379d7bSStefano Zampini graph->xadj = 0; 35604d379d7bSStefano Zampini graph->adjncy = 0; 35614d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 35624d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 35634d379d7bSStefano Zampini } 3564674ae819SStefano Zampini } 35659b28b941SStefano Zampini if (pcbddc->dbg_flag) { 35669b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3567674ae819SStefano Zampini } 3568674ae819SStefano Zampini 356963602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3570674ae819SStefano Zampini vertex_size = 1; 357163602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 357263602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 357395ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 357463602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3575e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 357663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3577674ae819SStefano Zampini } 357863602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 357963602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 358063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3581674ae819SStefano Zampini } 358263602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3583674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 358463602bcaSStefano Zampini } else { 358563602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 358663602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3587854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 358863602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 358963602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 359063602bcaSStefano Zampini } 359163602bcaSStefano Zampini } 3592674ae819SStefano Zampini } 3593674ae819SStefano Zampini 3594674ae819SStefano Zampini /* Setup of Graph */ 3595785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3596e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3597785d1243SStefano Zampini } 3598785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3599e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3600785d1243SStefano Zampini } 3601302440fdSBarry Smith ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices);CHKERRQ(ierr); 3602674ae819SStefano Zampini 3603674ae819SStefano Zampini /* Graph's connected components analysis */ 3604674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3605674ae819SStefano Zampini 3606674ae819SStefano Zampini /* print some info to stdout */ 3607674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3608302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3609674ae819SStefano Zampini } 3610fb180af4SStefano Zampini 3611fb180af4SStefano Zampini /* mark topography has done */ 3612fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3613674ae819SStefano Zampini PetscFunctionReturn(0); 3614674ae819SStefano Zampini } 3615674ae819SStefano Zampini 3616dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3617674ae819SStefano Zampini #undef __FUNCT__ 3618674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3619dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3620674ae819SStefano Zampini { 3621dc456d91SStefano Zampini PetscSF sf; 3622dc456d91SStefano Zampini PetscLayout map; 3623dc456d91SStefano Zampini const PetscInt *idxs; 3624dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 3625dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 3626dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 3627dc456d91SStefano Zampini PetscMPIInt commsize; 3628674ae819SStefano Zampini PetscBool first_found; 3629674ae819SStefano Zampini PetscErrorCode ierr; 3630674ae819SStefano Zampini 3631674ae819SStefano Zampini PetscFunctionBegin; 3632dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 3633dc456d91SStefano Zampini if (subset_mult) { 3634dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 3635dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 3636dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 3637674ae819SStefano Zampini } 3638dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 3639dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 3640dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 3641dc456d91SStefano Zampini for (i=0;i<n;i++) { 3642dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 3643dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 3644674ae819SStefano Zampini } 3645dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 3646dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3647dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 3648dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 3649dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 3650dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 3651dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 3652dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 3653dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 3654dc456d91SStefano Zampini 3655dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 3656dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 3657dc456d91SStefano Zampini if (subset_mult) { 3658dc456d91SStefano Zampini const PetscInt* idxs_mult; 3659dc456d91SStefano Zampini 3660dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3661dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 3662dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3663674ae819SStefano Zampini } else { 3664dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 3665674ae819SStefano Zampini } 3666dc456d91SStefano Zampini /* local size of new subset */ 3667dc456d91SStefano Zampini n_n = 0; 3668dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 3669dc456d91SStefano Zampini 3670dc456d91SStefano Zampini /* global indexes in layout */ 3671dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 3672dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 3673dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 3674dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 3675dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 3676dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 3677dc456d91SStefano Zampini 3678dc456d91SStefano Zampini /* reduce from leaves to roots */ 3679dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 368064a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 368164a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 3682dc456d91SStefano Zampini 3683dc456d91SStefano Zampini /* count indexes in local part of layout */ 3684674ae819SStefano Zampini nlocals = 0; 3685674ae819SStefano Zampini first_index = -1; 3686674ae819SStefano Zampini first_found = PETSC_FALSE; 3687dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 3688dc456d91SStefano Zampini if (!first_found && root_data[i]) { 3689674ae819SStefano Zampini first_found = PETSC_TRUE; 3690674ae819SStefano Zampini first_index = i; 3691674ae819SStefano Zampini } 3692dc456d91SStefano Zampini nlocals += root_data[i]; 3693674ae819SStefano Zampini } 3694dc456d91SStefano Zampini 3695dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 36965fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 3697dc456d91SStefano Zampini start = 0; 369864a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 36995fa240b1SStefano Zampini #else 370064a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 37015fa240b1SStefano Zampini start = start-nlocals; 37025fa240b1SStefano Zampini #endif 37035fa240b1SStefano Zampini 3704dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 3705dc456d91SStefano Zampini *N_n = start + nlocals; 3706dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 3707dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3708674ae819SStefano Zampini } 37095fa240b1SStefano Zampini 37105fa240b1SStefano Zampini /* adapt root data with cumulative */ 3711674ae819SStefano Zampini if (first_found) { 3712dc456d91SStefano Zampini PetscInt old_index; 3713dc456d91SStefano Zampini 3714dc456d91SStefano Zampini root_data[first_index] += start; 3715674ae819SStefano Zampini old_index = first_index; 3716dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 3717dc456d91SStefano Zampini if (root_data[i]) { 3718dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 3719674ae819SStefano Zampini old_index = i; 3720674ae819SStefano Zampini } 3721674ae819SStefano Zampini } 3722674ae819SStefano Zampini } 3723dc456d91SStefano Zampini 3724dc456d91SStefano Zampini /* from roots to leaves */ 3725dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3726dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3727dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 3728dc456d91SStefano Zampini 3729dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 3730dc456d91SStefano Zampini if (subset_mult) { 3731dc456d91SStefano Zampini const PetscInt* idxs_mult; 3732dc456d91SStefano Zampini PetscInt cum; 3733dc456d91SStefano Zampini 3734dc456d91SStefano Zampini cum = 0; 3735dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3736dc456d91SStefano Zampini for (i=0;i<n;i++) { 3737dc456d91SStefano Zampini PetscInt j; 3738dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 3739674ae819SStefano Zampini } 3740dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3741674ae819SStefano Zampini } else { 3742dc456d91SStefano Zampini for (i=0;i<n;i++) { 3743dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 3744674ae819SStefano Zampini } 3745674ae819SStefano Zampini } 3746dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 3747dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 3748674ae819SStefano Zampini PetscFunctionReturn(0); 3749674ae819SStefano Zampini } 37509a7d3425SStefano Zampini 37519a7d3425SStefano Zampini #undef __FUNCT__ 37529a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 37539a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 37549a7d3425SStefano Zampini { 37559a7d3425SStefano Zampini PetscInt i,j; 37569a7d3425SStefano Zampini PetscScalar *alphas; 37579a7d3425SStefano Zampini PetscErrorCode ierr; 37589a7d3425SStefano Zampini 37599a7d3425SStefano Zampini PetscFunctionBegin; 37609a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 3761785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 37629a7d3425SStefano Zampini for (i=0;i<n;i++) { 37639a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 37649a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 37659a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 37669a7d3425SStefano Zampini } 37679a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 37689a7d3425SStefano Zampini PetscFunctionReturn(0); 37699a7d3425SStefano Zampini } 37709a7d3425SStefano Zampini 3771e7931f94SStefano Zampini #undef __FUNCT__ 377270cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 3773b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 3774e7931f94SStefano Zampini { 377552e5ac9dSStefano Zampini IS ranks_send_to; 3776e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 3777e7931f94SStefano Zampini PetscMPIInt size,rank,color; 377852e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 377952e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 37803837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 37812b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 3782e7931f94SStefano Zampini PetscSubcomm subcomm; 378352e5ac9dSStefano Zampini PetscErrorCode ierr; 3784a57a6d2fSStefano Zampini 3785e7931f94SStefano Zampini PetscFunctionBegin; 37862b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 37872b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 37882b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 3789e7931f94SStefano Zampini 3790e7931f94SStefano Zampini /* Get info on mapping */ 37913bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 37923bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3793e7931f94SStefano Zampini 3794e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 3795785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 3796e7931f94SStefano Zampini xadj[0] = 0; 3797e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 3798785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 3799785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 3800e7931f94SStefano Zampini 38012b510759SStefano Zampini if (threshold) { 3802d023bfaeSStefano Zampini PetscInt xadj_count = 0; 38032b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 3804d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 3805d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 3806d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 3807d023bfaeSStefano Zampini xadj_count++; 3808e7931f94SStefano Zampini } 3809e7931f94SStefano Zampini } 3810d023bfaeSStefano Zampini xadj[1] = xadj_count; 3811c8587f34SStefano Zampini } else { 3812e7931f94SStefano Zampini if (xadj[1]) { 3813e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 3814e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 3815c8587f34SStefano Zampini } 3816e7931f94SStefano Zampini } 38173bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3818e7931f94SStefano Zampini if (use_square) { 3819e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3820e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3821e7931f94SStefano Zampini } 3822e7931f94SStefano Zampini } 3823e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3824e7931f94SStefano Zampini 38253837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3826e7931f94SStefano Zampini 3827e7931f94SStefano Zampini /* 3828e7931f94SStefano Zampini Restrict work on active processes only. 3829e7931f94SStefano Zampini */ 3830e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3831e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3832e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 38332b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3834d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3835e7931f94SStefano Zampini if (color) { 3836e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3837e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3838e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3839c8587f34SStefano Zampini } else { 384052e5ac9dSStefano Zampini Mat subdomain_adj; 384152e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 384252e5ac9dSStefano Zampini MatPartitioning partitioner; 384352e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 384452e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 3845b0c7d250SStefano Zampini PetscBool aggregate; 3846b0c7d250SStefano Zampini 3847306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 3848785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3849e7931f94SStefano Zampini prank = rank; 3850306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 38518002ef2cSStefano Zampini /* 3852e7931f94SStefano Zampini for (i=0;i<size;i++) { 3853e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3854c8587f34SStefano Zampini } 38558002ef2cSStefano Zampini */ 3856e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3857e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3858c8587f34SStefano Zampini } 3859e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3860b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 3861b0c7d250SStefano Zampini if (aggregate) { 3862b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 3863b0c7d250SStefano Zampini PetscMPIInt nrank; 3864b0c7d250SStefano Zampini PetscScalar *vals; 3865b0c7d250SStefano Zampini 3866b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 3867b0c7d250SStefano Zampini lrows = 0; 3868b0c7d250SStefano Zampini if (nrank<redprocs) { 3869b0c7d250SStefano Zampini lrows = size/redprocs; 3870b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 3871b0c7d250SStefano Zampini } 38725fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 3873b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 3874b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3875b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3876b0c7d250SStefano Zampini row = nrank; 3877b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 3878b0c7d250SStefano Zampini cols = adjncy; 3879b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 3880b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 3881b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 3882b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3883b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 388452e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 388552e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 388652e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3887b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 3888b0c7d250SStefano Zampini } else { 3889306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 3890b0c7d250SStefano Zampini } 389122b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3892e7931f94SStefano Zampini 3893e7931f94SStefano Zampini /* Partition */ 3894306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 3895e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3896e7931f94SStefano Zampini if (use_vwgt) { 38973837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3898e7931f94SStefano Zampini v_wgt[0] = local_size; 3899e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3900c8587f34SStefano Zampini } 390128143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 390228143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3903e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3904e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 390522b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3906e7931f94SStefano Zampini 390752e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 390852e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 390952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 391052e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3911b0c7d250SStefano Zampini if (!redprocs) { 3912b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 391328143c3dSStefano Zampini } else { 3914b0c7d250SStefano Zampini PetscInt idxs[1]; 3915b0c7d250SStefano Zampini PetscMPIInt tag; 3916b0c7d250SStefano Zampini MPI_Request *reqs; 3917b0c7d250SStefano Zampini 3918b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 3919b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 3920b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 3921b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 392228143c3dSStefano Zampini } 3923b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 3924b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3925b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 3926b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 3927e7931f94SStefano Zampini } 392852e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3929e7931f94SStefano Zampini /* clean up */ 3930e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 393152e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 3932e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3933e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3934e7931f94SStefano Zampini } 3935e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3936e7931f94SStefano Zampini 3937e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3938e7931f94SStefano Zampini i = 1; 3939e7931f94SStefano Zampini if (color) i=0; 3940e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3941e7931f94SStefano Zampini /* get back IS */ 3942e7931f94SStefano Zampini *is_sends = ranks_send_to; 3943e7931f94SStefano Zampini PetscFunctionReturn(0); 3944e7931f94SStefano Zampini } 3945e7931f94SStefano Zampini 3946e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3947e7931f94SStefano Zampini 3948e7931f94SStefano Zampini #undef __FUNCT__ 3949e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 395053a05cb3SStefano 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[]) 3951e7931f94SStefano Zampini { 395270cf5478SStefano Zampini Mat local_mat; 3953e7931f94SStefano Zampini IS is_sends_internal; 39549d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 395528143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 39569d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3957e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3958e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3959e7931f94SStefano Zampini const PetscInt* is_indices; 3960e7931f94SStefano Zampini MatType new_local_type; 3961e7931f94SStefano Zampini /* buffers */ 3962e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 396328143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 39649d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3965e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3966e7931f94SStefano Zampini /* MPI */ 396728143c3dSStefano Zampini MPI_Comm comm,comm_n; 396828143c3dSStefano Zampini PetscSubcomm subcomm; 3969e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 397028143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 397128143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 397228143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 397328143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 397428143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3975e7931f94SStefano Zampini PetscErrorCode ierr; 3976e7931f94SStefano Zampini 3977e7931f94SStefano Zampini PetscFunctionBegin; 397828143c3dSStefano Zampini /* TODO: add missing checks */ 397928143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 398028143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 398128143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 398228143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3983e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 398428143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3985e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3986e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3987e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3988e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3989e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 399028143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 399170cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 399270cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 399328143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 399470cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 399570cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 399670cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 399770cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 399870cf5478SStefano Zampini } 3999e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4000e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4001e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4002e7931f94SStefano Zampini if (!is_sends) { 400328143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4004b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4005c8587f34SStefano Zampini } else { 4006e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4007e7931f94SStefano Zampini is_sends_internal = is_sends; 4008c8587f34SStefano Zampini } 4009e7931f94SStefano Zampini 4010e7931f94SStefano Zampini /* get comm */ 4011a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4012e7931f94SStefano Zampini 4013e7931f94SStefano Zampini /* compute number of sends */ 4014e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4015e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4016e7931f94SStefano Zampini 4017e7931f94SStefano Zampini /* compute number of receives */ 4018e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4019785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4020e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4021e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4022e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4023e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4024e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4025e7931f94SStefano Zampini 402628143c3dSStefano Zampini /* restrict comm if requested */ 402728143c3dSStefano Zampini subcomm = 0; 402828143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 402928143c3dSStefano Zampini if (restrict_comm) { 4030779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4031779c1cceSStefano Zampini 403228143c3dSStefano Zampini color = 0; 403353a05cb3SStefano Zampini if (restrict_full) { 403453a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 403553a05cb3SStefano Zampini } else { 403653a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 403753a05cb3SStefano Zampini } 403828143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 403928143c3dSStefano Zampini subcommsize = commsize - subcommsize; 404028143c3dSStefano Zampini /* check if reuse has been requested */ 404128143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 404228143c3dSStefano Zampini if (*mat_n) { 404328143c3dSStefano Zampini PetscMPIInt subcommsize2; 404428143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 404528143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 404628143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 404728143c3dSStefano Zampini } else { 404828143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 404928143c3dSStefano Zampini } 405028143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4051779c1cceSStefano Zampini PetscMPIInt rank; 4052779c1cceSStefano Zampini 4053779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 405428143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 405528143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 405628143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4057306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 405828143c3dSStefano Zampini } 405928143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 406028143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 406128143c3dSStefano Zampini } else { 406228143c3dSStefano Zampini comm_n = comm; 406328143c3dSStefano Zampini } 406428143c3dSStefano Zampini 4065e7931f94SStefano Zampini /* prepare send/receive buffers */ 4066785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4067e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4068785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4069e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 407028143c3dSStefano Zampini if (nis) { 4071854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 407228143c3dSStefano Zampini } 4073e7931f94SStefano Zampini 407428143c3dSStefano Zampini /* Get data from local matrices */ 4075e7931f94SStefano Zampini if (!isdense) { 4076a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4077e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4078e7931f94SStefano Zampini /* 4079e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4080e7931f94SStefano Zampini send_buffer_idxs should contain: 4081e7931f94SStefano Zampini - MatType_PRIVATE type 4082e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4083e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4084e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4085e7931f94SStefano Zampini */ 4086e7931f94SStefano Zampini } else { 4087e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 40883bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4089854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4090e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4091e7931f94SStefano Zampini send_buffer_idxs[1] = i; 40923bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4093e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 40943bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4095e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4096e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4097e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4098e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4099c8587f34SStefano Zampini } 4100c8587f34SStefano Zampini } 4101e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 410228143c3dSStefano Zampini /* additional is (if any) */ 410328143c3dSStefano Zampini if (nis) { 410428143c3dSStefano Zampini PetscMPIInt psum; 410528143c3dSStefano Zampini PetscInt j; 410628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 410728143c3dSStefano Zampini PetscInt plen; 410828143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 410928143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 411028143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 411128143c3dSStefano Zampini } 4112854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 411328143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 411428143c3dSStefano Zampini PetscInt plen; 411528143c3dSStefano Zampini const PetscInt *is_array_idxs; 411628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 411728143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 411828143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 411928143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 412028143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 412128143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 412228143c3dSStefano Zampini } 412328143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 412428143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 412528143c3dSStefano Zampini } 412628143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 412728143c3dSStefano Zampini } 412828143c3dSStefano Zampini 4129e7931f94SStefano Zampini buf_size_idxs = 0; 4130e7931f94SStefano Zampini buf_size_vals = 0; 413128143c3dSStefano Zampini buf_size_idxs_is = 0; 4132e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4133e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4134e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 413528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4136e7931f94SStefano Zampini } 4137785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4138785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 413995ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4140e7931f94SStefano Zampini 4141e7931f94SStefano Zampini /* get new tags for clean communications */ 4142e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4143e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 414428143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4145e7931f94SStefano Zampini 4146e7931f94SStefano Zampini /* allocate for requests */ 4147785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4148785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 414995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4150785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4151785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 415295ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4153e7931f94SStefano Zampini 4154e7931f94SStefano Zampini /* communications */ 4155e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4156e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 415728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4158e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4159e7931f94SStefano Zampini source_dest = onodes[i]; 4160e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4161e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4162e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4163e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 416428143c3dSStefano Zampini if (nis) { 416528143c3dSStefano 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); 416628143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 416728143c3dSStefano Zampini } 4168e7931f94SStefano Zampini } 4169e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4170e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4171e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4172e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 417328143c3dSStefano Zampini if (nis) { 417428143c3dSStefano 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); 417528143c3dSStefano Zampini } 4176e7931f94SStefano Zampini } 4177e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4178e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4179e7931f94SStefano Zampini 4180e7931f94SStefano Zampini /* assemble new l2g map */ 4181e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4182e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 41839d30be91SStefano Zampini new_local_rows = 0; 4184e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 41859d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4186e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4187e7931f94SStefano Zampini } 41889d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4189e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 41909d30be91SStefano Zampini new_local_rows = 0; 4191e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 41929d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 41939d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4194e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4195e7931f94SStefano Zampini } 41969d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 41979d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4198e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4199e7931f94SStefano Zampini 4200e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4201e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4202e7931f94SStefano 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) */ 4203e7931f94SStefano Zampini if (n_recvs) { 420428143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4205e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4206e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4207e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4208e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4209e7931f94SStefano Zampini break; 4210e7931f94SStefano Zampini } 4211e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4212e7931f94SStefano Zampini } 4213e7931f94SStefano Zampini switch (new_local_type_private) { 421428143c3dSStefano Zampini case MATDENSE_PRIVATE: 421528143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4216e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4217e7931f94SStefano Zampini bs = 1; 421828143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 421928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 422028143c3dSStefano Zampini bs = 1; 422128143c3dSStefano Zampini } 4222e7931f94SStefano Zampini break; 4223e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4224e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4225e7931f94SStefano Zampini bs = 1; 4226e7931f94SStefano Zampini break; 4227e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4228e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4229e7931f94SStefano Zampini break; 4230e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4231e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4232e7931f94SStefano Zampini break; 4233e7931f94SStefano Zampini default: 42349d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4235e7931f94SStefano Zampini break; 4236e7931f94SStefano Zampini } 423728143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 423828143c3dSStefano Zampini new_local_type = MATSEQDENSE; 423928143c3dSStefano Zampini bs = 1; 4240e7931f94SStefano Zampini } 4241e7931f94SStefano Zampini 424270cf5478SStefano Zampini /* create MATIS object if needed */ 424370cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4244e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4245e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 424670cf5478SStefano Zampini } else { 424770cf5478SStefano Zampini /* it also destroys the local matrices */ 424870cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 424970cf5478SStefano Zampini } 425070cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4251e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 42529d30be91SStefano Zampini 42539d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 42549d30be91SStefano Zampini 42559d30be91SStefano Zampini /* Global to local map of received indices */ 42569d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 42579d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 42589d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 42599d30be91SStefano Zampini 42609d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 42619d30be91SStefano Zampini buf_size_idxs = 0; 42629d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 42639d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 42649d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 42659d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 42669d30be91SStefano Zampini } 42679d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 42689d30be91SStefano Zampini 42699d30be91SStefano Zampini /* set preallocation */ 42709d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 42719d30be91SStefano Zampini if (!newisdense) { 42729d30be91SStefano Zampini PetscInt *new_local_nnz=0; 42739d30be91SStefano Zampini 42749d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 42759d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 42769d30be91SStefano Zampini if (n_recvs) { 42779d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 42789d30be91SStefano Zampini } 42799d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 42809d30be91SStefano Zampini PetscInt j; 42819d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 42829d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 42839d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 42849d30be91SStefano Zampini } 42859d30be91SStefano Zampini } else { 42869d30be91SStefano Zampini /* TODO */ 42879d30be91SStefano Zampini } 42889d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 42899d30be91SStefano Zampini } 42909d30be91SStefano Zampini if (new_local_nnz) { 42919d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 42929d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 42939d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 42949d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 42959d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 42969d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 42979d30be91SStefano Zampini } else { 42989d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 42999d30be91SStefano Zampini } 43009d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 43019d30be91SStefano Zampini } else { 43029d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 43039d30be91SStefano Zampini } 4304e7931f94SStefano Zampini 4305e7931f94SStefano Zampini /* set values */ 4306e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 43079d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 4308e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4309e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 4310e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 43119d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 4312e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4313e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4314e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 431528143c3dSStefano Zampini } else { 431628143c3dSStefano Zampini /* TODO */ 4317e7931f94SStefano Zampini } 4318e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4319e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 4320e7931f94SStefano Zampini } 4321e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4322e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 432370cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 432470cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43259d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 43269d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 4327e7931f94SStefano Zampini 4328dfd14d43SStefano Zampini #if 0 432928143c3dSStefano Zampini if (!restrict_comm) { /* check */ 4330e7931f94SStefano Zampini Vec lvec,rvec; 4331e7931f94SStefano Zampini PetscReal infty_error; 4332e7931f94SStefano Zampini 43332a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 4334e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 4335e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 4336e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 433770cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 4338e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4339e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 4340e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 4341e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 4342e7931f94SStefano Zampini } 434328143c3dSStefano Zampini #endif 4344e7931f94SStefano Zampini 434528143c3dSStefano Zampini /* assemble new additional is (if any) */ 434628143c3dSStefano Zampini if (nis) { 434728143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 434828143c3dSStefano Zampini 434928143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4350854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 435128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 435228143c3dSStefano Zampini psum = 0; 435328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 435428143c3dSStefano Zampini for (j=0;j<nis;j++) { 435528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 435628143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 435728143c3dSStefano Zampini psum += plen; 435828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 435928143c3dSStefano Zampini } 436028143c3dSStefano Zampini } 4361854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 4362854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 436328143c3dSStefano Zampini for (i=1;i<nis;i++) { 436428143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 436528143c3dSStefano Zampini } 436628143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 436728143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 436828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 436928143c3dSStefano Zampini for (j=0;j<nis;j++) { 437028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 437128143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 437228143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 437328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 437428143c3dSStefano Zampini } 437528143c3dSStefano Zampini } 437628143c3dSStefano Zampini for (i=0;i<nis;i++) { 437728143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 437828143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 437928143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 438028143c3dSStefano Zampini } 438128143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 438228143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 438328143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 438428143c3dSStefano Zampini } 4385e7931f94SStefano Zampini /* free workspace */ 438628143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4387e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4388e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4389e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4390e7931f94SStefano Zampini if (isdense) { 4391e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4392e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4393e7931f94SStefano Zampini } else { 4394e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4395e7931f94SStefano Zampini } 439628143c3dSStefano Zampini if (nis) { 439728143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 439828143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 439928143c3dSStefano Zampini } 4400e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4401e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 440228143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4403e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4404e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 440528143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4406e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4407e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4408e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4409e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4410e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 441128143c3dSStefano Zampini if (nis) { 441228143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 441328143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 441428143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 441528143c3dSStefano Zampini } 441628143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 441728143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 441828143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 441928143c3dSStefano Zampini for (i=0;i<nis;i++) { 442028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 442128143c3dSStefano Zampini } 442253a05cb3SStefano Zampini *mat_n = NULL; 442328143c3dSStefano Zampini } 4424e7931f94SStefano Zampini PetscFunctionReturn(0); 4425e7931f94SStefano Zampini } 4426a57a6d2fSStefano Zampini 442712edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4428af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 442912edc857SStefano Zampini 4430c8587f34SStefano Zampini #undef __FUNCT__ 4431c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4432c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4433c8587f34SStefano Zampini { 4434c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4435c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 443620a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 44379881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 443820a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 44396e683305SStefano Zampini IS coarse_is,*isarray; 44406e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 44416e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 4442f9eb5b7dSStefano Zampini PC pc_temp; 4443c8587f34SStefano Zampini PCType coarse_pc_type; 4444c8587f34SStefano Zampini KSPType coarse_ksp_type; 4445f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 44464f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 44476e683305SStefano Zampini Mat t_coarse_mat_is; 44486e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 44496e683305SStefano Zampini PetscMPIInt all_procs; 445074e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 445168457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 445222bc73bbSStefano Zampini PetscScalar *array; 44539881197aSStefano Zampini PetscErrorCode ierr; 4454fdc09c96SStefano Zampini 4455c8587f34SStefano Zampini PetscFunctionBegin; 4456c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 445768457ee5SStefano 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 */ 4458fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 44595a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4460fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4461f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4462f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4463f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4464fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 446551bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 446651bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4467dc4bcba2SStefano Zampini PC pc; 4468dc4bcba2SStefano Zampini PetscBool isbddc; 4469dc4bcba2SStefano Zampini 4470dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4471dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4472dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4473dc4bcba2SStefano Zampini if (isbddc) { 4474dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4475dc4bcba2SStefano Zampini } 4476727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4477fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4478fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4479fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4480f4ddd8eeSStefano Zampini } 4481fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4482fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4483f4ddd8eeSStefano Zampini } 448470cf5478SStefano Zampini /* reset any subassembling information */ 448570cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 44866e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 44876e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4488fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4489f4ddd8eeSStefano Zampini } 4490c8587f34SStefano Zampini 44916e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 44922b510759SStefano Zampini im_active = !!(pcis->n); 44932b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 44946e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 44956e683305SStefano Zampini void_procs = all_procs-active_procs; 44966e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 449774e2c79eSStefano Zampini redist = PETSC_FALSE; 449822bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 44996e683305SStefano Zampini csin_ml = PETSC_TRUE; 45006e683305SStefano Zampini ncoarse_ml = void_procs; 4501779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4502779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 45036e683305SStefano Zampini csin_ds = PETSC_TRUE; 450418a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 450518a45a71SStefano Zampini redist = PETSC_TRUE; 450618a45a71SStefano Zampini } else { 45076e683305SStefano Zampini csin_ds = PETSC_TRUE; 4508779c1cceSStefano Zampini ncoarse_ds = active_procs; 4509779c1cceSStefano Zampini redist = PETSC_TRUE; 451018a45a71SStefano Zampini } 45116e683305SStefano Zampini } else { 45126e683305SStefano Zampini csin_ml = PETSC_FALSE; 45136e683305SStefano Zampini ncoarse_ml = all_procs; 45146e683305SStefano Zampini if (void_procs) { 45156e683305SStefano Zampini csin_ds = PETSC_TRUE; 45166e683305SStefano Zampini ncoarse_ds = void_procs; 45176e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 45186e683305SStefano Zampini } else { 4519779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 452074e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 452174e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 452274e2c79eSStefano Zampini redist = PETSC_TRUE; 452374e2c79eSStefano Zampini } else { 45246e683305SStefano Zampini csin_ds = PETSC_FALSE; 45256e683305SStefano Zampini ncoarse_ds = all_procs; 45266e683305SStefano Zampini } 45276e683305SStefano Zampini } 452874e2c79eSStefano Zampini } 45296e683305SStefano Zampini 45306e683305SStefano Zampini /* 45316e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 45326e683305SStefano Zampini - we have not exceeded the number of levels requested 45336e683305SStefano Zampini - we can actually subassemble the active processes 45346e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 45356e683305SStefano Zampini */ 45366e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 45376e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 45386e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 45396e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 45406e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4541f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 45422b510759SStefano Zampini } else { 4543f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4544c8587f34SStefano Zampini } 4545c8587f34SStefano Zampini } 45466e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 45476e683305SStefano Zampini if (multilevel_allowed) { 45486e683305SStefano Zampini ncoarse = ncoarse_ml; 45496e683305SStefano Zampini csin = csin_ml; 455058da7f69SStefano Zampini redist = PETSC_FALSE; 45516e683305SStefano Zampini } else { 45526e683305SStefano Zampini ncoarse = ncoarse_ds; 45536e683305SStefano Zampini csin = csin_ds; 45546e683305SStefano Zampini } 4555e7931f94SStefano Zampini 4556abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4557abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4558abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4559abbbba34SStefano Zampini 4560abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 456122bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 456222bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 456322bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 456422bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4565b1ecc7b1SStefano Zampini #if 0 4566b9b85e73SStefano Zampini { 4567b9b85e73SStefano Zampini PetscViewer viewer; 4568b9b85e73SStefano Zampini char filename[256]; 4569b1ecc7b1SStefano Zampini sprintf(filename,"local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4570b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4571b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4572b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 4573b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4574b9b85e73SStefano Zampini } 4575b9b85e73SStefano Zampini #endif 4576e176bc59SStefano 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); 45776e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 45786e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45796e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4580abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4581abbbba34SStefano Zampini 45826e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 45836e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 45846e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 45856e683305SStefano Zampini const PetscInt *idxs; 45866e683305SStefano Zampini ISLocalToGlobalMapping tmap; 45876e683305SStefano Zampini 45886e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 45890be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 45906e683305SStefano Zampini /* allocate space for temporary storage */ 4591854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4592854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 45936e683305SStefano Zampini /* allocate for IS array */ 45946e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 45956e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 45966e683305SStefano Zampini nis = nisdofs + nisneu; 4597854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 45986e683305SStefano Zampini /* dofs splitting */ 45996e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 46006e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 46016e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 46026e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 46036e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 46046e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 46056e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 46066e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 46076e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 46086e683305SStefano Zampini } 46096e683305SStefano Zampini /* neumann boundaries */ 46106e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 46116e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 46126e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 46136e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 46146e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 46156e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 46166e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 46176e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 46186e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 46196e683305SStefano Zampini } 46206e683305SStefano Zampini /* free memory */ 46216e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 46226e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 46236e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 46246e683305SStefano Zampini } else { 46256e683305SStefano Zampini nis = 0; 46266e683305SStefano Zampini nisdofs = 0; 46276e683305SStefano Zampini nisneu = 0; 46286e683305SStefano Zampini isarray = NULL; 46296e683305SStefano Zampini } 46306e683305SStefano Zampini /* destroy no longer needed map */ 46316e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 46326e683305SStefano Zampini 46336e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 46346e683305SStefano Zampini coarse_mat_is = NULL; 46356e683305SStefano Zampini if (csin) { 46366e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 463774e2c79eSStefano Zampini if (redist) { 463874e2c79eSStefano Zampini PetscMPIInt rank; 4639779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 464074e2c79eSStefano Zampini 464174e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 464258da7f69SStefano Zampini spc = active_procs/ncoarse; 464358da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 4644779c1cceSStefano Zampini if (im_active) { 4645779c1cceSStefano Zampini destsize = 1; 464674e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 464774e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 464874e2c79eSStefano Zampini } else { 464974e2c79eSStefano Zampini dest[0] = rank/(spc+1); 465074e2c79eSStefano Zampini } 465174e2c79eSStefano Zampini } else { 4652779c1cceSStefano Zampini destsize = 0; 46536e683305SStefano Zampini } 4654779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4655779c1cceSStefano Zampini } else if (csin_type_simple) { 46566e683305SStefano Zampini PetscMPIInt rank; 46576e683305SStefano Zampini PetscInt issize,isidx; 4658779c1cceSStefano Zampini 46596e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 46606e683305SStefano Zampini if (im_active) { 46616e683305SStefano Zampini issize = 1; 46626e683305SStefano Zampini isidx = (PetscInt)rank; 46636e683305SStefano Zampini } else { 46646e683305SStefano Zampini issize = 0; 46656e683305SStefano Zampini isidx = -1; 46666e683305SStefano Zampini } 46676e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4668779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 4669b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 46706e683305SStefano Zampini } 4671779c1cceSStefano Zampini 4672779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 4673779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 4674779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 4675779c1cceSStefano Zampini PetscInt *coarse_candidates; 4676779c1cceSStefano Zampini const PetscInt* tisindices; 4677779c1cceSStefano Zampini 4678779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 4679779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 4680779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4681779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 4682779c1cceSStefano Zampini if (!coarse_candidates[i]) { 4683779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 4684779c1cceSStefano Zampini } 4685779c1cceSStefano Zampini } 4686779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 4687779c1cceSStefano Zampini 4688779c1cceSStefano Zampini 46896e683305SStefano Zampini if (pcbddc->dbg_flag) { 46906e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 46916e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 46926e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 46936e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 4694779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 46956e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 46966e683305SStefano Zampini } 46976e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 46986e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 46996e683305SStefano Zampini } 47006e683305SStefano Zampini /* shift the pattern on coarse candidates */ 47016e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 47026e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 4703854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 47046e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 47056e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 47066e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 47076e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 47086e683305SStefano Zampini } 47096e683305SStefano Zampini if (pcbddc->dbg_flag) { 47106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47116e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 47126e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 47136e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47146e683305SStefano Zampini } 4715779c1cceSStefano Zampini } 47166e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 471753a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 471853a05cb3SStefano 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); 471953a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 472053a05cb3SStefano 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); 472153a05cb3SStefano Zampini } 47226e683305SStefano Zampini } else { 47236e683305SStefano Zampini if (pcbddc->dbg_flag) { 47246e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47256e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 47266e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47276e683305SStefano Zampini } 47286e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 47296e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 47306e683305SStefano Zampini } 47316e683305SStefano Zampini 47326e683305SStefano Zampini /* create local to global scatters for coarse problem */ 473368457ee5SStefano Zampini if (compute_vecs) { 47346e683305SStefano Zampini PetscInt lrows; 47356e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 47366e683305SStefano Zampini if (coarse_mat_is) { 47376e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 47386e683305SStefano Zampini } else { 47396e683305SStefano Zampini lrows = 0; 47406e683305SStefano Zampini } 47416e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 47426e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 47436e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 47446e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 47456e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 47466e683305SStefano Zampini } 47476e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 47486e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 4749c8587f34SStefano Zampini 4750f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 4751f9eb5b7dSStefano Zampini if (multilevel_allowed) { 4752f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 4753f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 4754f9eb5b7dSStefano Zampini } else { 4755f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 4756f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 4757c8587f34SStefano Zampini } 4758c8587f34SStefano Zampini 47596e683305SStefano Zampini /* print some info if requested */ 47606e683305SStefano Zampini if (pcbddc->dbg_flag) { 47616e683305SStefano Zampini if (!multilevel_allowed) { 47626e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47636e683305SStefano Zampini if (multilevel_requested) { 47646e683305SStefano 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); 47656e683305SStefano Zampini } else if (pcbddc->max_levels) { 47666e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 47676e683305SStefano Zampini } 47686e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47696e683305SStefano Zampini } 47706e683305SStefano Zampini } 47716e683305SStefano Zampini 4772f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 47736e683305SStefano Zampini if (coarse_mat_is) { 47746e683305SStefano Zampini MatReuse coarse_mat_reuse; 47756a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 47766e683305SStefano Zampini if (pcbddc->dbg_flag) { 47776e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 47786e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 47796e683305SStefano Zampini } 4780f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 4781312be037SStefano Zampini char prefix[256],str_level[16]; 4782e604994aSStefano Zampini size_t len; 47836e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 4784422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 4785c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 4786f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 47875f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 4788c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 47896e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 4790c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4791c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4792e604994aSStefano Zampini /* prefix */ 4793e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 4794e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4795e604994aSStefano Zampini if (!pcbddc->current_level) { 4796e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4797e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 4798c8587f34SStefano Zampini } else { 4799e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4800312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4801312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 480234d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4803312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4804e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 4805e604994aSStefano Zampini } 4806e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 48073e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 48083e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 48093e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 48103e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 4811f9eb5b7dSStefano Zampini /* allow user customization */ 4812f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 48133e3c6dadSStefano Zampini } 48143e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 481551bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 48163e3c6dadSStefano Zampini if (nisdofs) { 48173e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 48183e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 48193e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 48203e3c6dadSStefano Zampini } 48213e3c6dadSStefano Zampini } 48223e3c6dadSStefano Zampini if (nisneu) { 48233e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 48243e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 4825312be037SStefano Zampini } 4826f9eb5b7dSStefano Zampini 4827f9eb5b7dSStefano Zampini /* get some info after set from options */ 4828f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 4829f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 48304f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 48316e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 4832f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4833f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 4834f9eb5b7dSStefano Zampini } 483539f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 48364f3a063dSStefano Zampini if (isredundant) { 48374f3a063dSStefano Zampini KSP inner_ksp; 48384f3a063dSStefano Zampini PC inner_pc; 48394f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 48404f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 48414f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 48424f3a063dSStefano Zampini } 4843f9eb5b7dSStefano Zampini 4844f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 4845fa7f1dd8SStefano Zampini if (coarse_reuse) { 484681d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 4847fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 48486e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 4849fa7f1dd8SStefano Zampini } else { 48506e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 4851fa7f1dd8SStefano Zampini } 4852c8587f34SStefano Zampini if (isbddc || isnn) { 485322bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 485470cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 4855b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 485622b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 48576e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 48586e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 48596e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 48606e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 486122b6e8a2SStefano Zampini } 486270cf5478SStefano Zampini } 486353a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 486470cf5478SStefano Zampini } else { 486522bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 486622bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 486722bc73bbSStefano Zampini } 486822bc73bbSStefano Zampini } else { 48692e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 4870c8587f34SStefano Zampini } 4871c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 4872c8587f34SStefano Zampini 48733301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 48745a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 48753301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 48763301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 48773301b35fSStefano Zampini } 48783301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 48793301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 48803301b35fSStefano Zampini } 48813301b35fSStefano Zampini if (pc->pmat->spd_set) { 48823301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 48833301b35fSStefano Zampini } 48846e683305SStefano Zampini /* set operators */ 48855f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 48866e683305SStefano Zampini if (pcbddc->dbg_flag) { 48876e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 48886e683305SStefano Zampini } 48896e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 48906e683305SStefano Zampini coarse_mat = 0; 48916e683305SStefano Zampini } 48926e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 4893b1ecc7b1SStefano Zampini #if 0 4894b9b85e73SStefano Zampini { 4895b9b85e73SStefano Zampini PetscViewer viewer; 4896b9b85e73SStefano Zampini char filename[256]; 4897b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 4898b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 4899b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4900b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 4901b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4902b9b85e73SStefano Zampini } 4903b9b85e73SStefano Zampini #endif 4904c8587f34SStefano Zampini 4905c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 4906298c0119SStefano Zampini #if 0 4907c8587f34SStefano Zampini if (pcbddc->NullSpace) { 4908c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 490998a51de6SStefano Zampini } 4910298c0119SStefano Zampini #endif 4911b0f5fe93SStefano Zampini /* hack */ 491298a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 491398a51de6SStefano Zampini Vec crhs,csol; 491404708bb6SStefano Zampini 4915f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4916f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 4917f347579bSStefano Zampini if (!csol) { 49182a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4919f9eb5b7dSStefano Zampini } 4920f347579bSStefano Zampini if (!crhs) { 49212a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4922f347579bSStefano Zampini } 4923b0f5fe93SStefano Zampini } 4924b0f5fe93SStefano Zampini 4925b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 4926b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 4927b0f5fe93SStefano Zampini 4928b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 4929b0f5fe93SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-1,1.0,INSERT_VALUES);CHKERRQ(ierr); 4930b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 4931b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 4932b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4933b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4934b0f5fe93SStefano Zampini if (coarse_mat) { 4935b0f5fe93SStefano Zampini Vec nullv; 4936b0f5fe93SStefano Zampini PetscScalar *array,*array2; 4937b0f5fe93SStefano Zampini PetscInt nl; 4938b0f5fe93SStefano Zampini 4939b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 4940b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 4941b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 4942b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 4943b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 4944b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 4945b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 4946b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 4947b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 4948b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 4949b0f5fe93SStefano Zampini } 4950b0f5fe93SStefano Zampini } 4951b0f5fe93SStefano Zampini 4952b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 4953b0f5fe93SStefano Zampini PetscBool ispreonly; 4954b0f5fe93SStefano Zampini 4955b0f5fe93SStefano Zampini if (CoarseNullSpace) { 4956b0f5fe93SStefano Zampini PetscBool isnull; 4957b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 4958b0f5fe93SStefano Zampini if (isnull) { 4959b0f5fe93SStefano Zampini if (isbddc) { 4960b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4961b0f5fe93SStefano Zampini } else { 4962b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 4963b0f5fe93SStefano Zampini } 4964b0f5fe93SStefano Zampini } else { 4965b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4966b0f5fe93SStefano Zampini } 4967b0f5fe93SStefano Zampini } 4968b0f5fe93SStefano Zampini /* setup coarse ksp */ 4969b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4970cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4971cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 49726e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4973c8587f34SStefano Zampini KSP check_ksp; 49742b510759SStefano Zampini KSPType check_ksp_type; 4975c8587f34SStefano Zampini PC check_pc; 49766e683305SStefano Zampini Vec check_vec,coarse_vec; 49776a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 49782b510759SStefano Zampini PetscInt its; 49796e683305SStefano Zampini PetscBool compute_eigs; 49806e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 49816e683305SStefano Zampini PetscInt neigs; 49828e185a42SStefano Zampini const char *prefix; 4983c8587f34SStefano Zampini 49842b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 49856e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 4986422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 498723ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4988f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 49892b510759SStefano Zampini if (ispreonly) { 49902b510759SStefano Zampini check_ksp_type = KSPPREONLY; 49916e683305SStefano Zampini compute_eigs = PETSC_FALSE; 49922b510759SStefano Zampini } else { 4993cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 49946e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4995c8587f34SStefano Zampini } 4996c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 49976e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 49986e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 49996e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5000a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5001a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5002a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5003a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5004c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5005c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5006c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5007c8587f34SStefano Zampini /* create random vec */ 50086e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 50096e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5010c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5011c8587f34SStefano Zampini if (CoarseNullSpace) { 5012c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5013c8587f34SStefano Zampini } 50146e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5015c8587f34SStefano Zampini /* solve coarse problem */ 50166e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5017c8587f34SStefano Zampini if (CoarseNullSpace) { 50186e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5019c8587f34SStefano Zampini } 5020cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 50216e683305SStefano Zampini if (compute_eigs) { 5022854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5023854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 50246e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 50256e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 50266e683305SStefano Zampini lambda_min = eigs_r[0]; 50276e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 50286e683305SStefano Zampini if (lambda_max>lambda_min) { 5029cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5030cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5031cbcc2c2aSStefano Zampini } 5032c8587f34SStefano Zampini } 5033c8587f34SStefano Zampini } 5034cbcc2c2aSStefano Zampini 5035c8587f34SStefano Zampini /* check coarse problem residual error */ 50366e683305SStefano Zampini if (pcbddc->dbg_flag) { 50376e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 50386e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 50396e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5040c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 50416e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 50426e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5043c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5044779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 50456e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 50466e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 50476e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 50486e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5049b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5050b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5051b0f5fe93SStefano Zampini } 50526e683305SStefano Zampini if (compute_eigs) { 50536e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5054deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5055c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 50566e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 50576e683305SStefano 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); 50586e683305SStefano Zampini for (i=0;i<neigs;i++) { 50596e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5060c8587f34SStefano Zampini } 50616e683305SStefano Zampini } 50626e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 50636e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 50646e683305SStefano Zampini } 5065c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 50666e683305SStefano Zampini if (compute_eigs) { 50676e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 50686e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5069c8587f34SStefano Zampini } 50706e683305SStefano Zampini } 50716e683305SStefano Zampini } 5072cbcc2c2aSStefano Zampini /* print additional info */ 5073cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 50746e683305SStefano Zampini /* waits until all processes reaches this point */ 50756e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5076cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5077cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5078cbcc2c2aSStefano Zampini } 5079cbcc2c2aSStefano Zampini 50802b510759SStefano Zampini /* free memory */ 5081c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5082fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5083c8587f34SStefano Zampini PetscFunctionReturn(0); 5084c8587f34SStefano Zampini } 5085674ae819SStefano Zampini 5086f34684f1SStefano Zampini #undef __FUNCT__ 5087f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5088f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5089f34684f1SStefano Zampini { 5090f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5091f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5092f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5093dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5094dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 509573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5096dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5097f34684f1SStefano Zampini PetscErrorCode ierr; 5098f34684f1SStefano Zampini 5099f34684f1SStefano Zampini PetscFunctionBegin; 5100f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 51010e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 51020e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5103727cdba6SStefano Zampini } 5104dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 51053bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5106dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5107dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5108dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5109dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5110dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5111dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 51120e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 51130e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 51140e6343abSStefano Zampini } 5115dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5116dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5117dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5118dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5119dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5120f34684f1SStefano Zampini 5121f34684f1SStefano Zampini /* check numbering */ 5122f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5123019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5124dc456d91SStefano Zampini PetscInt i; 5125b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5126f34684f1SStefano Zampini 5127f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5128f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5129f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 51300fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 5131019a44ceSStefano Zampini /* counter */ 5132019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5133019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5134019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5135019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5136019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5137019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5138019a44ceSStefano Zampini 5139f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5140f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5141727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5142f34684f1SStefano Zampini } 5143f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5144f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5145f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5146e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5147e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5148e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5149e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5150f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5151019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5152f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5153019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 5154*75c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 5155*75c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5156b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5157019a44ceSStefano 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); 5158f34684f1SStefano Zampini } 5159f34684f1SStefano Zampini } 5160019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5161b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5162f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5163f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5164f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5165f34684f1SStefano Zampini } 5166f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5167f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5168e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5169e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5170f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5171f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5172b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5173ca8b9ea9SStefano Zampini PetscInt *gidxs; 5174ca8b9ea9SStefano Zampini 5175ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 51763bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5177f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5178f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5179f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5180f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 51814bc2dc4bSStefano 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); 5182f34684f1SStefano Zampini } 5183f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5184ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5185f34684f1SStefano Zampini } 5186f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5187302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5188f34684f1SStefano Zampini } 51898bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5190f34684f1SStefano Zampini /* get back data */ 5191f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5192f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5193674ae819SStefano Zampini PetscFunctionReturn(0); 5194674ae819SStefano Zampini } 5195674ae819SStefano Zampini 5196e456f2a8SStefano Zampini #undef __FUNCT__ 5197e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5198a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5199e456f2a8SStefano Zampini { 5200e456f2a8SStefano Zampini IS localis_t; 5201a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5202e456f2a8SStefano Zampini PetscScalar *vals; 5203e456f2a8SStefano Zampini PetscErrorCode ierr; 5204e456f2a8SStefano Zampini 5205e456f2a8SStefano Zampini PetscFunctionBegin; 5206a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5207e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5208854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5209e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5210e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5211a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5212a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 52131035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5214a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 52151035eff8SStefano Zampini } 5216a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5217e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5218e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5219a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5220a7dc3881SStefano Zampini /* now compute set in local ordering */ 5221a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5222a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5223a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5224a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5225a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5226ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5227e456f2a8SStefano Zampini lsize++; 5228e456f2a8SStefano Zampini } 5229e456f2a8SStefano Zampini } 5230854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5231a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5232ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5233e456f2a8SStefano Zampini idxs[lsize++] = i; 5234e456f2a8SStefano Zampini } 5235e456f2a8SStefano Zampini } 5236a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5237a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5238e456f2a8SStefano Zampini *localis = localis_t; 5239e456f2a8SStefano Zampini PetscFunctionReturn(0); 5240e456f2a8SStefano Zampini } 5241906d46d4SStefano Zampini 5242906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5243906d46d4SStefano Zampini #undef __FUNCT__ 5244906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5245906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5246906d46d4SStefano Zampini { 5247906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5248906d46d4SStefano Zampini PetscErrorCode ierr; 5249906d46d4SStefano Zampini 5250906d46d4SStefano Zampini PetscFunctionBegin; 5251906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5252906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5253906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5254906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5255906d46d4SStefano Zampini PetscFunctionReturn(0); 5256906d46d4SStefano Zampini } 5257906d46d4SStefano Zampini 5258906d46d4SStefano Zampini #undef __FUNCT__ 5259906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5260906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5261906d46d4SStefano Zampini { 5262906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5263906d46d4SStefano Zampini PetscErrorCode ierr; 5264906d46d4SStefano Zampini 5265906d46d4SStefano Zampini PetscFunctionBegin; 5266906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5267906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5268906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5269906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5270906d46d4SStefano Zampini PetscFunctionReturn(0); 5271906d46d4SStefano Zampini } 5272b96c3477SStefano Zampini 5273b96c3477SStefano Zampini #undef __FUNCT__ 5274b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 527508122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5276b96c3477SStefano Zampini { 5277a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5278b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5279b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5280a64f4aa4SStefano Zampini Mat S_j; 5281b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 5282b96c3477SStefano Zampini PetscBool free_used_adj; 5283b96c3477SStefano Zampini PetscErrorCode ierr; 5284b96c3477SStefano Zampini 5285b96c3477SStefano Zampini PetscFunctionBegin; 5286b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 5287b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 528808122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 5289b96c3477SStefano Zampini used_xadj = NULL; 5290b96c3477SStefano Zampini used_adjncy = NULL; 5291b96c3477SStefano Zampini } else { 529208122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 529308122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 529408122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 529508122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 5296b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 5297b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 5298b96c3477SStefano Zampini } else { 52992fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 5300b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 5301b96c3477SStefano Zampini PetscInt nvtxs; 5302b96c3477SStefano Zampini 53032fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 53042fffb893SStefano Zampini if (flg_row) { 5305b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 5306b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 5307b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 5308b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 53092fffb893SStefano Zampini } else { 53102fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 53112fffb893SStefano Zampini used_xadj = NULL; 53122fffb893SStefano Zampini used_adjncy = NULL; 53132fffb893SStefano Zampini } 53142fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 5315b96c3477SStefano Zampini } 5316b96c3477SStefano Zampini } 5317d5574798SStefano Zampini 5318d5574798SStefano Zampini /* setup sub_schurs data */ 5319a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5320a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 5321a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 5322a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 532306a4e24aSStefano 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); 5324a64f4aa4SStefano Zampini } else { 53256816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 532604708bb6SStefano Zampini PetscBool isseqaij; 53275feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 53285feab87aSStefano Zampini PetscInt n_vertices; 53295feab87aSStefano Zampini 53305feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 53312034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 53325feab87aSStefano Zampini } 533304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 533404708bb6SStefano Zampini if (!isseqaij) { 533504708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 533604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 533704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 533804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 533904708bb6SStefano Zampini } else { 534004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 534104708bb6SStefano Zampini } 534204708bb6SStefano Zampini } 534306a4e24aSStefano 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); 5344a64f4aa4SStefano Zampini } 5345a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5346b96c3477SStefano Zampini 5347b96c3477SStefano Zampini /* free adjacency */ 5348b96c3477SStefano Zampini if (free_used_adj) { 5349b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 5350b96c3477SStefano Zampini } 5351b96c3477SStefano Zampini PetscFunctionReturn(0); 5352b96c3477SStefano Zampini } 5353b96c3477SStefano Zampini 5354b96c3477SStefano Zampini #undef __FUNCT__ 5355b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 535608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 5357b96c3477SStefano Zampini { 5358b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5359b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5360b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5361b96c3477SStefano Zampini PCBDDCGraph graph; 5362b96c3477SStefano Zampini PetscErrorCode ierr; 5363b96c3477SStefano Zampini 5364b96c3477SStefano Zampini PetscFunctionBegin; 5365b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 536608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 53673301b35fSStefano Zampini IS verticesIS,verticescomm; 53683301b35fSStefano Zampini PetscInt vsize,*idxs; 5369b96c3477SStefano Zampini 5370b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 53713301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 53723301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 53733301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 53743301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 53753301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 5376b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 53777fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 53783301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 53793301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 5380b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5381b96c3477SStefano Zampini /* 5382b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 5383b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5384b96c3477SStefano Zampini } 5385b96c3477SStefano Zampini */ 5386b96c3477SStefano Zampini } else { 5387b96c3477SStefano Zampini graph = pcbddc->mat_graph; 5388b96c3477SStefano Zampini } 5389b96c3477SStefano Zampini 5390b96c3477SStefano Zampini /* sub_schurs init */ 5391a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 5392a64f4aa4SStefano Zampini 5393b96c3477SStefano Zampini /* free graph struct */ 539408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 5395b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 5396b96c3477SStefano Zampini } 5397b96c3477SStefano Zampini PetscFunctionReturn(0); 5398b96c3477SStefano Zampini } 5399fa34dd3eSStefano Zampini 5400fa34dd3eSStefano Zampini #undef __FUNCT__ 5401fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 5402fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 5403fa34dd3eSStefano Zampini { 5404fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5405fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5406fa34dd3eSStefano Zampini PetscErrorCode ierr; 5407fa34dd3eSStefano Zampini 5408fa34dd3eSStefano Zampini PetscFunctionBegin; 5409fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 5410fa34dd3eSStefano Zampini IS zerodiag = NULL; 5411fa34dd3eSStefano Zampini Mat S_j,B0=NULL,B0_B=NULL; 5412fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 5413*75c01103SStefano Zampini PetscScalar p0_check,*array,*array2; 5414*75c01103SStefano Zampini PetscReal norm; 5415fa34dd3eSStefano Zampini PetscInt i; 5416fa34dd3eSStefano Zampini 5417fa34dd3eSStefano Zampini /* B0 and B0_B */ 5418fa34dd3eSStefano Zampini if (zerodiag) { 5419fa34dd3eSStefano Zampini IS dummy; 5420fa34dd3eSStefano Zampini PetscInt ii[2]; 5421fa34dd3eSStefano Zampini 5422fa34dd3eSStefano Zampini ii[0] = 0; 5423fa34dd3eSStefano Zampini ii[1] = pcbddc->B0_ncol; 5424fa34dd3eSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,1,pcis->n,ii,pcbddc->B0_cols,pcbddc->B0_vals,&B0);CHKERRQ(ierr); 5425fa34dd3eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,1,0,1,&dummy);CHKERRQ(ierr); 5426fa34dd3eSStefano Zampini ierr = MatGetSubMatrix(B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 5427fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 5428fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 5429fa34dd3eSStefano Zampini } 5430fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 5431fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 5432fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 5433fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5434fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5435fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5436fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5437fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 5438fa34dd3eSStefano Zampini /* S_j */ 5439fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5440fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 5441fa34dd3eSStefano Zampini 5442fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 5443fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 5444fa34dd3eSStefano Zampini /* continuous in primal space */ 5445fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 5446fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5447fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5448fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5449fa34dd3eSStefano Zampini if (zerodiag) { 5450fa34dd3eSStefano Zampini p0_check = array[pcbddc->local_primal_size-1]; 5451fa34dd3eSStefano Zampini } else { 5452fa34dd3eSStefano Zampini p0_check = 0; 5453fa34dd3eSStefano Zampini } 5454fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5455fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5456fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5457fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5458fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5459fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5460fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 5461fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 5462fa34dd3eSStefano Zampini 5463fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 5464fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 5465fa34dd3eSStefano Zampini /* local with Schur */ 5466fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 5467fa34dd3eSStefano Zampini if (zerodiag) { 5468fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 5469fa34dd3eSStefano Zampini array[0] = p0_check; 5470fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5471fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5472fa34dd3eSStefano Zampini } 5473fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 5474fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5475fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5476fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5477fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5478fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 5479fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5480fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5481fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 5482fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5483fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5484fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5485fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5486fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5487fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 5488fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 5489fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5490fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5491fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5492fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5493fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5494fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5495fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 5496fa34dd3eSStefano Zampini if (zerodiag) { 5497fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 5498fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 5499fa34dd3eSStefano Zampini pcbddc->benign_p0 = array[0]; 5500fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5501fa34dd3eSStefano Zampini } else { 5502fa34dd3eSStefano Zampini pcbddc->benign_p0 = 0.; 5503fa34dd3eSStefano Zampini } 5504fa34dd3eSStefano Zampini /* BDDC */ 5505fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 5506fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 5507fa34dd3eSStefano Zampini 5508fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 5509fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 5510fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 5511fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 5512fa34dd3eSStefano Zampini if (pcbddc->benign_p0_lidx >= 0) { 5513fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0 error is %1.4e\n",PetscGlobalRank,PetscAbsScalar(pcbddc->benign_p0-p0_check)); 5514fa34dd3eSStefano Zampini } 5515fa34dd3eSStefano Zampini 5516fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 5517fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 5518fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 5519fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5520fa34dd3eSStefano Zampini ierr = MatDestroy(&B0);CHKERRQ(ierr); 5521fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 5522fa34dd3eSStefano Zampini } 5523fa34dd3eSStefano Zampini PetscFunctionReturn(0); 5524fa34dd3eSStefano Zampini } 5525