1*414d97d3SAlp Dener #include <../src/tao/bound/impls/bqnk/bqnk.h> /*I "petsctao.h" I*/ /*I "petscmat.h" I*/ 2e0ed867bSAlp Dener #include <petscksp.h> 3e0ed867bSAlp Dener 470a3f44bSAlp Dener static const char *BQNK_INIT[64] = {"constant", "direction"}; 570a3f44bSAlp Dener static const char *BNK_UPDATE[64] = {"step", "reduction", "interpolation"}; 670a3f44bSAlp Dener static const char *BNK_AS[64] = {"none", "bertsekas"}; 770a3f44bSAlp Dener 8e0ed867bSAlp Dener static PetscErrorCode TaoBQNKComputeHessian(Tao tao) 9e0ed867bSAlp Dener { 10e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 11e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 12e0ed867bSAlp Dener PetscErrorCode ierr; 1365f5217aSAlp Dener PetscReal gnorm2, delta; 14e0ed867bSAlp Dener 15e0ed867bSAlp Dener PetscFunctionBegin; 16e0ed867bSAlp Dener /* Alias the LMVM matrix into the TAO hessian */ 17e0ed867bSAlp Dener if (tao->hessian) { 18e0ed867bSAlp Dener ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr); 19e0ed867bSAlp Dener } 20e0ed867bSAlp Dener if (tao->hessian_pre) { 21e0ed867bSAlp Dener ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr); 22e0ed867bSAlp Dener } 23e0ed867bSAlp Dener ierr = PetscObjectReference((PetscObject)bqnk->B);CHKERRQ(ierr); 24e0ed867bSAlp Dener tao->hessian = bqnk->B; 25e0ed867bSAlp Dener ierr = PetscObjectReference((PetscObject)bqnk->B);CHKERRQ(ierr); 26e0ed867bSAlp Dener tao->hessian_pre = bqnk->B; 27e0ed867bSAlp Dener /* Update the Hessian with the latest solution */ 28f5766c09SAlp Dener if (bqnk->is_spd) { 2965f5217aSAlp Dener gnorm2 = bnk->gnorm*bnk->gnorm; 308cabe928SAlp Dener if (gnorm2 == 0.0) gnorm2 = PETSC_MACHINE_EPSILON; 318cabe928SAlp Dener if (bnk->f == 0.0) { 328cabe928SAlp Dener delta = 2.0 / gnorm2; 338cabe928SAlp Dener } else { 348cabe928SAlp Dener delta = 2.0 * PetscAbsScalar(bnk->f) / gnorm2; 358cabe928SAlp Dener } 36864588a7SAlp Dener ierr = MatLMVMSymBroydenSetDelta(bqnk->B, delta);CHKERRQ(ierr); 37f5766c09SAlp Dener } 38e0ed867bSAlp Dener ierr = MatLMVMUpdate(tao->hessian, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 39e0ed867bSAlp Dener ierr = MatLMVMResetShift(tao->hessian);CHKERRQ(ierr); 40e0ed867bSAlp Dener /* Prepare the reduced sub-matrices for the inactive set */ 414f4fdda4SAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 42e0ed867bSAlp Dener if (bnk->active_idx) { 43e0ed867bSAlp Dener ierr = MatCreateSubMatrixVirtual(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, &bnk->H_inactive);CHKERRQ(ierr); 444f4fdda4SAlp Dener ierr = PCLMVMSetIS(bqnk->pc, bnk->inactive_idx);CHKERRQ(ierr); 45e0ed867bSAlp Dener } else { 46e0ed867bSAlp Dener ierr = PetscObjectReference((PetscObject)tao->hessian);CHKERRQ(ierr); 47e0ed867bSAlp Dener bnk->H_inactive = tao->hessian; 484f4fdda4SAlp Dener ierr = PCLMVMClearIS(bqnk->pc);CHKERRQ(ierr); 49e0ed867bSAlp Dener } 504f4fdda4SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 514f4fdda4SAlp Dener ierr = PetscObjectReference((PetscObject)bnk->H_inactive);CHKERRQ(ierr); 52e0ed867bSAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 53e0ed867bSAlp Dener PetscFunctionReturn(0); 54e0ed867bSAlp Dener } 55e0ed867bSAlp Dener 566b591159SAlp Dener static PetscErrorCode TaoBQNKComputeStep(Tao tao, PetscBool shift, KSPConvergedReason *ksp_reason, PetscInt *step_type) 57e0ed867bSAlp Dener { 58e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 59e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 60e0ed867bSAlp Dener PetscErrorCode ierr; 61e0ed867bSAlp Dener 62e0ed867bSAlp Dener PetscFunctionBegin; 636b591159SAlp Dener ierr = TaoBNKComputeStep(tao, shift, ksp_reason, step_type);CHKERRQ(ierr); 64e0ed867bSAlp Dener if (*ksp_reason < 0) { 65e0ed867bSAlp Dener /* Krylov solver failed to converge so reset the LMVM matrix */ 66e0ed867bSAlp Dener ierr = MatLMVMReset(bqnk->B, PETSC_FALSE);CHKERRQ(ierr); 676b591159SAlp Dener ierr = MatLMVMUpdate(bqnk->B, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 68e0ed867bSAlp Dener } 69e0ed867bSAlp Dener PetscFunctionReturn(0); 70e0ed867bSAlp Dener } 71e0ed867bSAlp Dener 72*414d97d3SAlp Dener PetscErrorCode TaoSolve_BQNK(Tao tao) 73*414d97d3SAlp Dener { 74*414d97d3SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 75*414d97d3SAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 76*414d97d3SAlp Dener Mat_LMVM *lmvm = (Mat_LMVM*)bqnk->B->data; 77*414d97d3SAlp Dener Mat_LMVM *J0; 78*414d97d3SAlp Dener Mat_SymBrdn *diag_ctx; 79*414d97d3SAlp Dener PetscBool flg = PETSC_FALSE; 80*414d97d3SAlp Dener PetscErrorCode ierr; 81*414d97d3SAlp Dener 82*414d97d3SAlp Dener PetscFunctionBegin; 83*414d97d3SAlp Dener if (!tao->recycle) { 84*414d97d3SAlp Dener ierr = MatLMVMReset(bqnk->B, PETSC_FALSE);CHKERRQ(ierr); 85*414d97d3SAlp Dener lmvm->nresets = 0; 86*414d97d3SAlp Dener if (lmvm->J0) { 87*414d97d3SAlp Dener ierr = PetscObjectBaseTypeCompare((PetscObject)lmvm->J0, MATLMVM, &flg);CHKERRQ(ierr); 88*414d97d3SAlp Dener if (flg) { 89*414d97d3SAlp Dener J0 = (Mat_LMVM*)lmvm->J0->data; 90*414d97d3SAlp Dener J0->nresets = 0; 91*414d97d3SAlp Dener } 92*414d97d3SAlp Dener } 93*414d97d3SAlp Dener flg = PETSC_FALSE; 94*414d97d3SAlp Dener ierr = PetscObjectTypeCompareAny((PetscObject)bqnk->B, &flg, MATLMVMSYMBROYDEN, MATLMVMSYMBADBROYDEN, MATLMVMBFGS, MATLMVMDFP, ""); 95*414d97d3SAlp Dener if (flg) { 96*414d97d3SAlp Dener diag_ctx = (Mat_SymBrdn*)lmvm->ctx; 97*414d97d3SAlp Dener J0 = (Mat_LMVM*)diag_ctx->D->data; 98*414d97d3SAlp Dener J0->nresets = 0; 99*414d97d3SAlp Dener } 100*414d97d3SAlp Dener } 101*414d97d3SAlp Dener ierr = (*bqnk->solve)(tao);CHKERRQ(ierr); 102*414d97d3SAlp Dener PetscFunctionReturn(0); 103*414d97d3SAlp Dener } 104*414d97d3SAlp Dener 1056b591159SAlp Dener PetscErrorCode TaoSetUp_BQNK(Tao tao) 1064f4fdda4SAlp Dener { 1074f4fdda4SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1084f4fdda4SAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 1094f4fdda4SAlp Dener PetscErrorCode ierr; 1104f4fdda4SAlp Dener PetscInt n, N; 1116b591159SAlp Dener PetscBool is_lmvm, is_sym, is_spd; 1124f4fdda4SAlp Dener 1134f4fdda4SAlp Dener PetscFunctionBegin; 1144f4fdda4SAlp Dener ierr = TaoSetUp_BNK(tao);CHKERRQ(ierr); 1154f4fdda4SAlp Dener ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr); 1164f4fdda4SAlp Dener ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr); 1174f4fdda4SAlp Dener ierr = MatSetSizes(bqnk->B, n, n, N, N);CHKERRQ(ierr); 1184f4fdda4SAlp Dener ierr = MatLMVMAllocate(bqnk->B,tao->solution,bnk->unprojected_gradient);CHKERRQ(ierr); 1194f4fdda4SAlp Dener ierr = PetscObjectBaseTypeCompare((PetscObject)bqnk->B, MATLMVM, &is_lmvm);CHKERRQ(ierr); 1204f4fdda4SAlp Dener if (!is_lmvm) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "Matrix must be an LMVM-type"); 1214f4fdda4SAlp Dener ierr = MatGetOption(bqnk->B, MAT_SYMMETRIC, &is_sym);CHKERRQ(ierr); 1224f4fdda4SAlp Dener if (!is_sym) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix must be symmetric"); 1236b591159SAlp Dener ierr = MatGetOption(bqnk->B, MAT_SPD, &is_spd);CHKERRQ(ierr); 1244f4fdda4SAlp Dener ierr = KSPGetPC(tao->ksp, &bqnk->pc);CHKERRQ(ierr); 1254f4fdda4SAlp Dener ierr = PCSetType(bqnk->pc, PCLMVM);CHKERRQ(ierr); 1264f4fdda4SAlp Dener ierr = PCLMVMSetMatLMVM(bqnk->pc, bqnk->B);CHKERRQ(ierr); 1274f4fdda4SAlp Dener PetscFunctionReturn(0); 1284f4fdda4SAlp Dener } 1294f4fdda4SAlp Dener 130e0ed867bSAlp Dener static PetscErrorCode TaoSetFromOptions_BQNK(PetscOptionItems *PetscOptionsObject,Tao tao) 131e0ed867bSAlp Dener { 132e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 133e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 134e0ed867bSAlp Dener PetscErrorCode ierr; 1356b591159SAlp Dener KSPType ksp_type; 136e0ed867bSAlp Dener 137e0ed867bSAlp Dener PetscFunctionBegin; 1384f4fdda4SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Quasi-Newton-Krylov method for bound constrained optimization");CHKERRQ(ierr); 13983c8fe1dSLisandro Dalcin ierr = PetscOptionsEList("-tao_bqnk_init_type", "radius initialization type", "", BQNK_INIT, BQNK_INIT_TYPES, BQNK_INIT[bnk->init_type], &bnk->init_type, NULL);CHKERRQ(ierr); 14083c8fe1dSLisandro Dalcin ierr = PetscOptionsEList("-tao_bqnk_update_type", "radius update type", "", BNK_UPDATE, BNK_UPDATE_TYPES, BNK_UPDATE[bnk->update_type], &bnk->update_type, NULL);CHKERRQ(ierr); 14183c8fe1dSLisandro Dalcin ierr = PetscOptionsEList("-tao_bqnk_as_type", "active set estimation method", "", BNK_AS, BNK_AS_TYPES, BNK_AS[bnk->as_type], &bnk->as_type, NULL);CHKERRQ(ierr); 1426b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_sval", "(developer) Hessian perturbation starting value", "", bnk->sval, &bnk->sval,NULL);CHKERRQ(ierr); 1436b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_imin", "(developer) minimum initial Hessian perturbation", "", bnk->imin, &bnk->imin,NULL);CHKERRQ(ierr); 1446b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_imax", "(developer) maximum initial Hessian perturbation", "", bnk->imax, &bnk->imax,NULL);CHKERRQ(ierr); 1456b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_imfac", "(developer) initial merit factor for Hessian perturbation", "", bnk->imfac, &bnk->imfac,NULL);CHKERRQ(ierr); 1466b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmin", "(developer) minimum Hessian perturbation", "", bnk->pmin, &bnk->pmin,NULL);CHKERRQ(ierr); 1476b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmax", "(developer) maximum Hessian perturbation", "", bnk->pmax, &bnk->pmax,NULL);CHKERRQ(ierr); 1486b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pgfac", "(developer) Hessian perturbation growth factor", "", bnk->pgfac, &bnk->pgfac,NULL);CHKERRQ(ierr); 1496b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_psfac", "(developer) Hessian perturbation shrink factor", "", bnk->psfac, &bnk->psfac,NULL);CHKERRQ(ierr); 1506b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmgfac", "(developer) merit growth factor for Hessian perturbation", "", bnk->pmgfac, &bnk->pmgfac,NULL);CHKERRQ(ierr); 1516b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmsfac", "(developer) merit shrink factor for Hessian perturbation", "", bnk->pmsfac, &bnk->pmsfac,NULL);CHKERRQ(ierr); 1526b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta1", "(developer) threshold for rejecting step (-tao_bqnk_update_type reduction)", "", bnk->eta1, &bnk->eta1,NULL);CHKERRQ(ierr); 1536b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta2", "(developer) threshold for accepting marginal step (-tao_bqnk_update_type reduction)", "", bnk->eta2, &bnk->eta2,NULL);CHKERRQ(ierr); 1546b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta3", "(developer) threshold for accepting reasonable step (-tao_bqnk_update_type reduction)", "", bnk->eta3, &bnk->eta3,NULL);CHKERRQ(ierr); 1556b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta4", "(developer) threshold for accepting good step (-tao_bqnk_update_type reduction)", "", bnk->eta4, &bnk->eta4,NULL);CHKERRQ(ierr); 1566b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_alpha1", "(developer) radius reduction factor for rejected step (-tao_bqnk_update_type reduction)", "", bnk->alpha1, &bnk->alpha1,NULL);CHKERRQ(ierr); 1576b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_alpha2", "(developer) radius reduction factor for marginally accepted bad step (-tao_bqnk_update_type reduction)", "", bnk->alpha2, &bnk->alpha2,NULL);CHKERRQ(ierr); 1586b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_alpha3", "(developer) radius increase factor for reasonable accepted step (-tao_bqnk_update_type reduction)", "", bnk->alpha3, &bnk->alpha3,NULL);CHKERRQ(ierr); 1596b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_alpha4", "(developer) radius increase factor for good accepted step (-tao_bqnk_update_type reduction)", "", bnk->alpha4, &bnk->alpha4,NULL);CHKERRQ(ierr); 1606b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_alpha5", "(developer) radius increase factor for very good accepted step (-tao_bqnk_update_type reduction)", "", bnk->alpha5, &bnk->alpha5,NULL);CHKERRQ(ierr); 1616b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_nu1", "(developer) threshold for small line-search step length (-tao_bqnk_update_type step)", "", bnk->nu1, &bnk->nu1,NULL);CHKERRQ(ierr); 1626b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_nu2", "(developer) threshold for reasonable line-search step length (-tao_bqnk_update_type step)", "", bnk->nu2, &bnk->nu2,NULL);CHKERRQ(ierr); 1636b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_nu3", "(developer) threshold for large line-search step length (-tao_bqnk_update_type step)", "", bnk->nu3, &bnk->nu3,NULL);CHKERRQ(ierr); 1646b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_nu4", "(developer) threshold for very large line-search step length (-tao_bqnk_update_type step)", "", bnk->nu4, &bnk->nu4,NULL);CHKERRQ(ierr); 1656b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_omega1", "(developer) radius reduction factor for very small line-search step length (-tao_bqnk_update_type step)", "", bnk->omega1, &bnk->omega1,NULL);CHKERRQ(ierr); 1666b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_omega2", "(developer) radius reduction factor for small line-search step length (-tao_bqnk_update_type step)", "", bnk->omega2, &bnk->omega2,NULL);CHKERRQ(ierr); 1676b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_omega3", "(developer) radius factor for decent line-search step length (-tao_bqnk_update_type step)", "", bnk->omega3, &bnk->omega3,NULL);CHKERRQ(ierr); 1686b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_omega4", "(developer) radius increase factor for large line-search step length (-tao_bqnk_update_type step)", "", bnk->omega4, &bnk->omega4,NULL);CHKERRQ(ierr); 1696b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_omega5", "(developer) radius increase factor for very large line-search step length (-tao_bqnk_update_type step)", "", bnk->omega5, &bnk->omega5,NULL);CHKERRQ(ierr); 1706b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_mu1", "(developer) threshold for accepting very good step (-tao_bqnk_update_type interpolation)", "", bnk->mu1, &bnk->mu1,NULL);CHKERRQ(ierr); 1716b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_mu2", "(developer) threshold for accepting good step (-tao_bqnk_update_type interpolation)", "", bnk->mu2, &bnk->mu2,NULL);CHKERRQ(ierr); 1726b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_gamma1", "(developer) radius reduction factor for rejected very bad step (-tao_bqnk_update_type interpolation)", "", bnk->gamma1, &bnk->gamma1,NULL);CHKERRQ(ierr); 1736b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_gamma2", "(developer) radius reduction factor for rejected bad step (-tao_bqnk_update_type interpolation)", "", bnk->gamma2, &bnk->gamma2,NULL);CHKERRQ(ierr); 1746b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_gamma3", "(developer) radius increase factor for accepted good step (-tao_bqnk_update_type interpolation)", "", bnk->gamma3, &bnk->gamma3,NULL);CHKERRQ(ierr); 1756b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_gamma4", "(developer) radius increase factor for accepted very good step (-tao_bqnk_update_type interpolation)", "", bnk->gamma4, &bnk->gamma4,NULL);CHKERRQ(ierr); 1766b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_theta", "(developer) trust region interpolation factor (-tao_bqnk_update_type interpolation)", "", bnk->theta, &bnk->theta,NULL);CHKERRQ(ierr); 1776b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_min_radius", "(developer) lower bound on initial radius", "", bnk->min_radius, &bnk->min_radius,NULL);CHKERRQ(ierr); 1786b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_max_radius", "(developer) upper bound on radius", "", bnk->max_radius, &bnk->max_radius,NULL);CHKERRQ(ierr); 1796b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_epsilon", "(developer) tolerance used when computing actual and predicted reduction", "", bnk->epsilon, &bnk->epsilon,NULL);CHKERRQ(ierr); 1806b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_as_tol", "(developer) initial tolerance used when estimating actively bounded variables", "", bnk->as_tol, &bnk->as_tol,NULL);CHKERRQ(ierr); 1816b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_as_step", "(developer) step length used when estimating actively bounded variables", "", bnk->as_step, &bnk->as_step,NULL);CHKERRQ(ierr); 1826b591159SAlp Dener ierr = PetscOptionsInt("-tao_bqnk_max_cg_its", "number of BNCG iterations to take for each Newton step", "", bnk->max_cg_its, &bnk->max_cg_its,NULL);CHKERRQ(ierr); 1834f4fdda4SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 1846b591159SAlp Dener ierr = TaoSetFromOptions(bnk->bncg);CHKERRQ(ierr); 1856b591159SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 1866b591159SAlp Dener ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 1876b591159SAlp Dener ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 18805de396fSBarry Smith ierr = PetscStrcmp(ksp_type,KSPNASH,&bnk->is_nash);CHKERRQ(ierr); 18905de396fSBarry Smith ierr = PetscStrcmp(ksp_type,KSPSTCG,&bnk->is_stcg);CHKERRQ(ierr); 19005de396fSBarry Smith ierr = PetscStrcmp(ksp_type,KSPGLTR,&bnk->is_gltr);CHKERRQ(ierr); 191e0ed867bSAlp Dener if (bnk->init_type == BNK_INIT_INTERPOLATION) bnk->init_type = BNK_INIT_DIRECTION; 192e0ed867bSAlp Dener ierr = MatSetFromOptions(bqnk->B);CHKERRQ(ierr); 193f5766c09SAlp Dener ierr = MatGetOption(bqnk->B, MAT_SPD, &bqnk->is_spd);CHKERRQ(ierr); 194e0ed867bSAlp Dener PetscFunctionReturn(0); 195e0ed867bSAlp Dener } 196e0ed867bSAlp Dener 197e0ed867bSAlp Dener static PetscErrorCode TaoView_BQNK(Tao tao, PetscViewer viewer) 198e0ed867bSAlp Dener { 199e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK*)tao->data; 200e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 201e0ed867bSAlp Dener PetscErrorCode ierr; 202e0ed867bSAlp Dener PetscBool isascii; 203e0ed867bSAlp Dener 204e0ed867bSAlp Dener PetscFunctionBegin; 205e0ed867bSAlp Dener ierr = TaoView_BNK(tao, viewer);CHKERRQ(ierr); 206e0ed867bSAlp Dener ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 207e0ed867bSAlp Dener if (isascii) { 208e0ed867bSAlp Dener ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 209e0ed867bSAlp Dener ierr = MatView(bqnk->B, viewer);CHKERRQ(ierr); 210e0ed867bSAlp Dener ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 211e0ed867bSAlp Dener } 212e0ed867bSAlp Dener PetscFunctionReturn(0); 213e0ed867bSAlp Dener } 214e0ed867bSAlp Dener 215e0ed867bSAlp Dener static PetscErrorCode TaoDestroy_BQNK(Tao tao) 216e0ed867bSAlp Dener { 217e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK*)tao->data; 218e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 219e0ed867bSAlp Dener PetscErrorCode ierr; 220e0ed867bSAlp Dener 221e0ed867bSAlp Dener PetscFunctionBegin; 2224f4fdda4SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 223cb384e1eSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 224e0ed867bSAlp Dener ierr = MatDestroy(&bqnk->B);CHKERRQ(ierr); 225e0ed867bSAlp Dener ierr = PetscFree(bnk->ctx);CHKERRQ(ierr); 226e0ed867bSAlp Dener ierr = TaoDestroy_BNK(tao);CHKERRQ(ierr); 227e0ed867bSAlp Dener PetscFunctionReturn(0); 228e0ed867bSAlp Dener } 229e0ed867bSAlp Dener 230e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoCreate_BQNK(Tao tao) 231e0ed867bSAlp Dener { 232e0ed867bSAlp Dener TAO_BNK *bnk; 233e0ed867bSAlp Dener TAO_BQNK *bqnk; 234e0ed867bSAlp Dener PetscErrorCode ierr; 235e0ed867bSAlp Dener 236e0ed867bSAlp Dener PetscFunctionBegin; 237e0ed867bSAlp Dener ierr = TaoCreate_BNK(tao);CHKERRQ(ierr); 238f4a59f9fSAlp Dener ierr = KSPSetOptionsPrefix(tao->ksp, "tao_bqnk_");CHKERRQ(ierr); 239*414d97d3SAlp Dener tao->ops->solve = TaoSolve_BQNK; 240e0ed867bSAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BQNK; 241e0ed867bSAlp Dener tao->ops->destroy = TaoDestroy_BQNK; 242e0ed867bSAlp Dener tao->ops->view = TaoView_BQNK; 2434f4fdda4SAlp Dener tao->ops->setup = TaoSetUp_BQNK; 244e0ed867bSAlp Dener 245e0ed867bSAlp Dener bnk = (TAO_BNK *)tao->data; 246e0ed867bSAlp Dener bnk->computehessian = TaoBQNKComputeHessian; 247e0ed867bSAlp Dener bnk->computestep = TaoBQNKComputeStep; 248e0ed867bSAlp Dener bnk->init_type = BNK_INIT_DIRECTION; 249e0ed867bSAlp Dener 250e0ed867bSAlp Dener ierr = PetscNewLog(tao,&bqnk);CHKERRQ(ierr); 251e0ed867bSAlp Dener bnk->ctx = (void*)bqnk; 252f5766c09SAlp Dener bqnk->is_spd = PETSC_TRUE; 253e0ed867bSAlp Dener 254e0ed867bSAlp Dener ierr = MatCreate(PetscObjectComm((PetscObject)tao), &bqnk->B);CHKERRQ(ierr); 255e0ed867bSAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)bqnk->B, (PetscObject)tao, 1);CHKERRQ(ierr); 256e0ed867bSAlp Dener ierr = MatSetOptionsPrefix(bqnk->B, "tao_bqnk_");CHKERRQ(ierr); 257e0ed867bSAlp Dener ierr = MatSetType(bqnk->B, MATLMVMSR1);CHKERRQ(ierr); 258e0ed867bSAlp Dener PetscFunctionReturn(0); 259e0ed867bSAlp Dener } 260f5766c09SAlp Dener 261*414d97d3SAlp Dener /*@ 262*414d97d3SAlp Dener TaoGetLMVMMatrix - Returns a pointer to the internal LMVM matrix. Valid 263*414d97d3SAlp Dener only for quasi-Newton family of methods. 264*414d97d3SAlp Dener 265*414d97d3SAlp Dener Input Parameters: 266*414d97d3SAlp Dener . tao - Tao solver context 267*414d97d3SAlp Dener 268*414d97d3SAlp Dener Output Parameters: 269*414d97d3SAlp Dener . B - LMVM matrix 270*414d97d3SAlp Dener 271*414d97d3SAlp Dener Level: advanced 272*414d97d3SAlp Dener 273*414d97d3SAlp Dener .seealso: TAOBQNLS, TAOBQNKLS, TAOBQNKTL, TAOBQNKTR, MATLMVM, TaoSetLMVMMatrix() 274*414d97d3SAlp Dener @*/ 275f5766c09SAlp Dener PetscErrorCode TaoGetLMVMMatrix(Tao tao, Mat *B) 276f5766c09SAlp Dener { 277f5766c09SAlp Dener TAO_BNK *bnk = (TAO_BNK*)tao->data; 278f5766c09SAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 279f5766c09SAlp Dener PetscErrorCode ierr; 280*414d97d3SAlp Dener PetscBool flg = PETSC_FALSE; 281f5766c09SAlp Dener 282f5766c09SAlp Dener PetscFunctionBegin; 283*414d97d3SAlp Dener ierr = PetscObjectTypeCompareAny((PetscObject)tao, &flg, TAOBQNLS, TAOBQNKLS, TAOBQNKTR, TAOBQNKTL, "");CHKERRQ(ierr); 284*414d97d3SAlp Dener if (!flg) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM Matrix only exists for quasi-Newton algorithms"); 285f5766c09SAlp Dener *B = bqnk->B; 286f5766c09SAlp Dener PetscFunctionReturn(0); 287f5766c09SAlp Dener } 288*414d97d3SAlp Dener 289*414d97d3SAlp Dener /*@ 290*414d97d3SAlp Dener TaoSetLMVMMatrix - Sets an external LMVM matrix into the Tao solver. Valid 291*414d97d3SAlp Dener only for quasi-Newton family of methods. 292*414d97d3SAlp Dener 293*414d97d3SAlp Dener QN family of methods create their own LMVM matrices and users who wish to 294*414d97d3SAlp Dener manipulate this matrix should use TaoGetLMVMMatrix() instead. 295*414d97d3SAlp Dener 296*414d97d3SAlp Dener Input Parameters: 297*414d97d3SAlp Dener + tao - Tao solver context 298*414d97d3SAlp Dener - B - LMVM matrix 299*414d97d3SAlp Dener 300*414d97d3SAlp Dener Level: advanced 301*414d97d3SAlp Dener 302*414d97d3SAlp Dener .seealso: TAOBQNLS, TAOBQNKLS, TAOBQNKTL, TAOBQNKTR, MATLMVM, TaoGetLMVMMatrix() 303*414d97d3SAlp Dener @*/ 304*414d97d3SAlp Dener PetscErrorCode TaoSetLMVMMatrix(Tao tao, Mat B) 305*414d97d3SAlp Dener { 306*414d97d3SAlp Dener TAO_BNK *bnk = (TAO_BNK*)tao->data; 307*414d97d3SAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 308*414d97d3SAlp Dener PetscErrorCode ierr; 309*414d97d3SAlp Dener PetscBool flg = PETSC_FALSE; 310*414d97d3SAlp Dener 311*414d97d3SAlp Dener PetscFunctionBegin; 312*414d97d3SAlp Dener ierr = PetscObjectTypeCompareAny((PetscObject)tao, &flg, TAOBQNLS, TAOBQNKLS, TAOBQNKTR, TAOBQNKTL, "");CHKERRQ(ierr); 313*414d97d3SAlp Dener if (!flg) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM Matrix only exists for quasi-Newton algorithms"); 314*414d97d3SAlp Dener ierr = PetscObjectBaseTypeCompare((PetscObject)B, MATLMVM, &flg);CHKERRQ(ierr); 315*414d97d3SAlp Dener if (!flg) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "Given matrix is not an LMVM matrix"); 316*414d97d3SAlp Dener if (bqnk->B) { 317*414d97d3SAlp Dener ierr = MatDestroy(&bqnk->B);CHKERRQ(ierr); 318*414d97d3SAlp Dener } 319*414d97d3SAlp Dener ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 320*414d97d3SAlp Dener bqnk->B = B; 321*414d97d3SAlp Dener PetscFunctionReturn(0); 322*414d97d3SAlp Dener }