PetscErrorCode PCBDDCScalingSetUp(PC pc) { PC_IS* pcis=(PC_IS*)pc->data; PC_BDDC* pcbddc=(PC_BDDC*)pc->data; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(pc,PC_CLASSID,1); ierr = PetscLogEventBegin(PC_BDDC_Scaling[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); /* create work vector for the operator */ ierr = VecDestroy(&pcbddc->work_scaling);CHKERRQ(ierr); ierr = VecDuplicate(pcis->vec1_B,&pcbddc->work_scaling);CHKERRQ(ierr); /* always rebuild pcis->D */ if (pcis->use_stiffness_scaling) { PetscScalar *a; PetscInt i,n; ierr = MatGetDiagonal(pcbddc->local_mat,pcis->vec1_N);CHKERRQ(ierr); ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecAbs(pcis->D);CHKERRQ(ierr); ierr = VecGetLocalSize(pcis->D,&n);CHKERRQ(ierr); ierr = VecGetArray(pcis->D,&a);CHKERRQ(ierr); for (i=0;i<n;i++) if (PetscAbsScalar(a[i])<PETSC_SMALL) a[i] = 1.0; ierr = VecRestoreArray(pcis->D,&a);CHKERRQ(ierr); } ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); ierr = VecScatterBegin(pcis->global_to_B,pcis->D,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcis->D,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecPointwiseDivide(pcis->D,pcis->D,pcis->vec1_B);CHKERRQ(ierr); /* now setup */ if (pcbddc->use_deluxe_scaling) { if (!pcbddc->deluxe_ctx) { ierr = PCBDDCScalingCreate_Deluxe(pc);CHKERRQ(ierr); } ierr = PCBDDCScalingSetUp_Deluxe(pc);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",PCBDDCScalingRestriction_Deluxe);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",PCBDDCScalingExtension_Deluxe);CHKERRQ(ierr); } else { ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",PCBDDCScalingRestriction_Basic);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",PCBDDCScalingExtension_Basic);CHKERRQ(ierr); } /* test */ if (pcbddc->dbg_flag) { Mat B0_B = NULL; Vec B0_Bv = NULL, B0_Bv2 = NULL; Vec vec2_global; PetscViewer viewer = pcbddc->dbg_viewer; PetscReal error; /* extension -> from local to parallel */ ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); ierr = VecSetRandom(pcis->vec1_B,NULL);CHKERRQ(ierr); ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecDuplicate(pcis->vec1_global,&vec2_global);CHKERRQ(ierr); ierr = VecCopy(pcis->vec1_global,vec2_global);CHKERRQ(ierr); ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (pcbddc->benign_n) { IS is_dummy; ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); ierr = MatCreateVecs(B0_B,NULL,&B0_Bv);CHKERRQ(ierr); ierr = VecDuplicate(B0_Bv,&B0_Bv2);CHKERRQ(ierr); ierr = MatMult(B0_B,pcis->vec1_B,B0_Bv);CHKERRQ(ierr); } ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,pcis->vec1_global);CHKERRQ(ierr); if (pcbddc->benign_saddle_point) { PetscReal errorl = 0.; ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (pcbddc->benign_n) { ierr = MatMult(B0_B,pcis->vec1_B,B0_Bv2);CHKERRQ(ierr); ierr = VecAXPY(B0_Bv,-1.0,B0_Bv2);CHKERRQ(ierr); ierr = VecNorm(B0_Bv,NORM_INFINITY,&errorl);CHKERRQ(ierr); } ierr = MPI_Allreduce(&errorl,&error,1,MPIU_REAL,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Error benign extension %1.14e\n",error);CHKERRQ(ierr); } ierr = VecAXPY(pcis->vec1_global,-1.0,vec2_global);CHKERRQ(ierr); ierr = VecNorm(pcis->vec1_global,NORM_INFINITY,&error);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Error scaling extension %1.14e\n",error);CHKERRQ(ierr); ierr = VecDestroy(&vec2_global);CHKERRQ(ierr); /* restriction -> from parallel to local */ ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); ierr = VecSetRandom(pcis->vec1_B,NULL);CHKERRQ(ierr); ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = PCBDDCScalingRestriction(pc,pcis->vec1_global,pcis->vec1_B);CHKERRQ(ierr); ierr = VecScale(pcis->vec1_B,-1.0);CHKERRQ(ierr); ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecNorm(pcis->vec1_global,NORM_INFINITY,&error);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Error scaling restriction %1.14e\n",error);CHKERRQ(ierr); ierr = MatDestroy(&B0_B);CHKERRQ(ierr); ierr = VecDestroy(&B0_Bv);CHKERRQ(ierr); ierr = VecDestroy(&B0_Bv2);CHKERRQ(ierr); } ierr = PetscLogEventEnd(PC_BDDC_Scaling[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode port_lsd_bfbt(void) { Mat A; Vec x,b; KSP ksp_A; PC pc_A; IS isu,isp; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = LoadTestMatrices(&A,&x,&b,&isu,&isp);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp_A);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(ksp_A,"fc_");CHKERRQ(ierr); ierr = KSPSetOperators(ksp_A,A,A);CHKERRQ(ierr); ierr = KSPGetPC(ksp_A,&pc_A);CHKERRQ(ierr); ierr = PCSetType(pc_A,PCFIELDSPLIT);CHKERRQ(ierr); ierr = PCFieldSplitSetBlockSize(pc_A,2);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc_A,"velocity",isu);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc_A,"pressure",isp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp_A);CHKERRQ(ierr); ierr = KSPSolve(ksp_A,b,x);CHKERRQ(ierr); /* Pull u,p out of x */ { PetscInt loc; PetscReal max,norm; PetscScalar sum; Vec uvec,pvec; VecScatter uscat,pscat; Mat A11,A22; /* grab matrices and create the compatable u,p vectors */ ierr = MatCreateSubMatrix(A,isu,isu,MAT_INITIAL_MATRIX,&A11);CHKERRQ(ierr); ierr = MatCreateSubMatrix(A,isp,isp,MAT_INITIAL_MATRIX,&A22);CHKERRQ(ierr); ierr = MatCreateVecs(A11,&uvec,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(A22,&pvec,NULL);CHKERRQ(ierr); /* perform the scatter from x -> (u,p) */ ierr = VecScatterCreateWithData(x,isu,uvec,NULL,&uscat);CHKERRQ(ierr); ierr = VecScatterBegin(uscat,x,uvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(uscat,x,uvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterCreateWithData(x,isp,pvec,NULL,&pscat);CHKERRQ(ierr); ierr = VecScatterBegin(pscat,x,pvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(pscat,x,pvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"-- vector vector values --\n"); ierr = VecMin(uvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Min(u) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecMax(uvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Max(u) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecNorm(uvec,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Norm(u) = %1.6f \n",(double)norm);CHKERRQ(ierr); ierr = VecSum(uvec,&sum);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Sum(u) = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"-- pressure vector values --\n"); ierr = VecMin(pvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Min(p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecMax(pvec,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Max(p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecNorm(pvec,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Norm(p) = %1.6f \n",(double)norm);CHKERRQ(ierr); ierr = VecSum(pvec,&sum);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Sum(p) = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"-- Full vector values --\n"); ierr = VecMin(x,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Min(u,p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecMax(x,&loc,&max);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Max(u,p) = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Norm(u,p) = %1.6f \n",(double)norm);CHKERRQ(ierr); ierr = VecSum(x,&sum);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Sum(u,p) = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr); ierr = VecScatterDestroy(&uscat);CHKERRQ(ierr); ierr = VecScatterDestroy(&pscat);CHKERRQ(ierr); ierr = VecDestroy(&uvec);CHKERRQ(ierr); ierr = VecDestroy(&pvec);CHKERRQ(ierr); ierr = MatDestroy(&A11);CHKERRQ(ierr); ierr = MatDestroy(&A22);CHKERRQ(ierr); } ierr = KSPDestroy(&ksp_A);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = ISDestroy(&isu);CHKERRQ(ierr); ierr = ISDestroy(&isp);CHKERRQ(ierr); PetscFunctionReturn(0); }