PetscErrorCode bsscr_buildK2(KSP ksp){ KSP_BSSCR *bsscr = (KSP_BSSCR *)ksp->data; Mat K,G,M, K2=0; Vec f2=0; PetscReal minD,maxD; //MatStokesBlockScaling BA=bsscr->BA; Stokes_SLE* stokesSLE = (Stokes_SLE*)bsscr->solver->st_sle; StokesBlockKSPInterface* Solver = bsscr->solver; //PetscErrorCode ierr; PetscFunctionBegin; K = stokesSLE->kStiffMat->matrix; G = stokesSLE->gStiffMat->matrix; if(bsscr->K2){ Stg_MatDestroy(&bsscr->K2); bsscr->K2 = PETSC_NULL; } switch (bsscr->k2type) { case (K2_DGMGD): {/* Should only do this one if scaling is turned off. */ Vec D=0; Vec MD = 0; Mat GKG = 0; Mat KG = 0; Mat Mscale = 0; //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (Solver->mStiffMat){ MatMatMult(K, G, MAT_INITIAL_MATRIX, PETSC_DEFAULT , &KG); MatTransposeMatMult(G, KG, MAT_INITIAL_MATRIX, PETSC_DEFAULT ,&GKG); MatGetVecs( GKG, PETSC_NULL, &MD ); MatGetDiagonal( GKG, MD ); M = Solver->mStiffMat->matrix; MatDuplicate(M, MAT_COPY_VALUES, &Mscale ); MatDiagonalScale(Mscale, NULL, MD ); VecMin(MD, PETSC_NULL, &minD); VecMax(MD, PETSC_NULL, &maxD); VecScale(MD, 1.0/maxD); VecMin(MD, PETSC_NULL, &minD); VecMax(MD, PETSC_NULL, &maxD); bsscr_GMiGt(&K2,K,G,Mscale); /* K2 created */ Stg_VecDestroy(&D); Stg_VecDestroy(&MD); Stg_MatDestroy(&GKG); Stg_MatDestroy(&KG); PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_DGMGD ------"); PetscPrintf( PETSC_COMM_WORLD, " min %f, max %f \n\n", minD, maxD); } else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method DGMGD was specified but the SLE has no mStiffMat on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n"); } } break; case (K2_GMG): { //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (Solver->mStiffMat){ M = Solver->mStiffMat->matrix; bsscr_GMiGt(&K2,K,G,M); /* K2 created */ PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_GMG ------\n\n"); }else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method GMG was specified but the SLE has no mStiffMat on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n"); } } break; case (K2_GG): { bsscr_GGt(&K2,K,G); /* K2 created */ PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_GG ------\n\n"); } break; case (K2_SLE): { //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (Solver->mStiffMat){ K2 = Solver->mStiffMat->matrix; if(Solver->jForceVec){ f2 = Solver->jForceVec->vector; } PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_SLE ------\n\n"); }else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method SLE was specified but the Solver has no Matrix on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to set the K2 matrix on the StokesBlockKSPInterface class.\n"); } } break; default: PetscPrintf( PETSC_COMM_WORLD, "\n\n----- NO K2 ------\n\n"); } bsscr->f2 = f2; bsscr->K2 = K2; PetscFunctionReturn(0); }
PetscErrorCode bsscr_buildK2(KSP ksp){ KSP_BSSCR *bsscr = (KSP_BSSCR *)ksp->data; Mat K,G,M, K2=0; Vec f2=0; //MatStokesBlockScaling BA=bsscr->BA; Stokes_SLE* stokesSLE = (Stokes_SLE*)bsscr->st_sle; //PetscErrorCode ierr; PetscFunctionBegin; K = stokesSLE->kStiffMat->matrix; G = stokesSLE->gStiffMat->matrix; if(bsscr->K2){ Stg_MatDestroy(&bsscr->K2); bsscr->K2 = PETSC_NULL; } switch (bsscr->k2type) { case (K2_DGMGD): {/* Should only do this one if scaling is turned off. */ Vec D; AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (stokesSLE->mStiffMat){ MatGetVecs( K, PETSC_NULL, &D ); //MatGetRowMax( K, D, PETSC_NULL ); MatGetDiagonal( K, D ); VecSqrt( D ); M = stokesSLE->mStiffMat->matrix; bsscr_GMiGt(&K2,K,G,M); /* K2 created */ MatDiagonalScale(K2, D, D ); /* K2 = D*G*inv(M)*Gt*D */ Stg_VecDestroy(&D); PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_DGMGD ------\n\n"); } else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method DGMGD was specified but the SLE has no mStiffMat on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n"); } } break; case (K2_GMG): { AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (stokesSLE->mStiffMat){ M = stokesSLE->mStiffMat->matrix; bsscr_GMiGt(&K2,K,G,M); /* K2 created */ PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_GMG ------\n\n"); }else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method GMG was specified but the SLE has no mStiffMat on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n"); } } break; case (K2_GG): { bsscr_GGt(&K2,K,G); /* K2 created */ PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_GG ------\n\n"); } break; case (K2_SLE): { AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle; if (stokesSLE->mStiffMat){ K2 = stokesSLE->mStiffMat->matrix; if(stokesSLE->jForceVec){ f2 = stokesSLE->jForceVec->vector; } PetscPrintf( PETSC_COMM_WORLD, "\n\n----- K2_SLE ------\n\n"); }else{ PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method SLE was specified but the SLE has no Matrix on it.\n"); PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n"); } } break; default: PetscPrintf( PETSC_COMM_WORLD, "\n\n----- NO K2 ------\n\n"); } bsscr->f2 = f2; bsscr->K2 = K2; PetscFunctionReturn(0); }