1e0ed867bSAlp Dener #include <../src/tao/bound/impls/bqnk/bqnk.h> 2e0ed867bSAlp Dener #include <petscksp.h> 3e0ed867bSAlp Dener 4e0ed867bSAlp Dener static PetscErrorCode TaoBQNKComputeHessian(Tao tao) 5e0ed867bSAlp Dener { 6e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 7e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 8e0ed867bSAlp Dener PetscErrorCode ierr; 9e0ed867bSAlp Dener 10e0ed867bSAlp Dener PetscFunctionBegin; 11e0ed867bSAlp Dener /* Alias the LMVM matrix into the TAO hessian */ 12e0ed867bSAlp Dener if (tao->hessian) { 13e0ed867bSAlp Dener ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr); 14e0ed867bSAlp Dener } 15e0ed867bSAlp Dener if (tao->hessian_pre) { 16e0ed867bSAlp Dener ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr); 17e0ed867bSAlp Dener } 18e0ed867bSAlp Dener ierr = PetscObjectReference((PetscObject)bqnk->B);CHKERRQ(ierr); 19e0ed867bSAlp Dener tao->hessian = bqnk->B; 20e0ed867bSAlp Dener ierr = PetscObjectReference((PetscObject)bqnk->B);CHKERRQ(ierr); 21e0ed867bSAlp Dener tao->hessian_pre = bqnk->B; 22e0ed867bSAlp Dener /* Update the Hessian with the latest solution */ 23e0ed867bSAlp Dener ierr = MatLMVMUpdate(tao->hessian, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 24e0ed867bSAlp Dener ierr = MatLMVMResetShift(tao->hessian);CHKERRQ(ierr); 25e0ed867bSAlp Dener /* Prepare the reduced sub-matrices for the inactive set */ 264f4fdda4SAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 27e0ed867bSAlp Dener if (bnk->active_idx) { 28e0ed867bSAlp Dener ierr = MatCreateSubMatrixVirtual(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, &bnk->H_inactive);CHKERRQ(ierr); 294f4fdda4SAlp Dener ierr = PCLMVMSetIS(bqnk->pc, bnk->inactive_idx);CHKERRQ(ierr); 30e0ed867bSAlp Dener } else { 31e0ed867bSAlp Dener ierr = PetscObjectReference((PetscObject)tao->hessian);CHKERRQ(ierr); 32e0ed867bSAlp Dener bnk->H_inactive = tao->hessian; 334f4fdda4SAlp Dener ierr = PCLMVMClearIS(bqnk->pc);CHKERRQ(ierr); 34e0ed867bSAlp Dener } 354f4fdda4SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 364f4fdda4SAlp Dener ierr = PetscObjectReference((PetscObject)bnk->H_inactive);CHKERRQ(ierr); 37e0ed867bSAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 38e0ed867bSAlp Dener PetscFunctionReturn(0); 39e0ed867bSAlp Dener } 40e0ed867bSAlp Dener 41*6b591159SAlp Dener static PetscErrorCode TaoBQNKComputeStep(Tao tao, PetscBool shift, KSPConvergedReason *ksp_reason, PetscInt *step_type) 42e0ed867bSAlp Dener { 43e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 44e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 45e0ed867bSAlp Dener PetscErrorCode ierr; 46e0ed867bSAlp Dener 47e0ed867bSAlp Dener PetscFunctionBegin; 48*6b591159SAlp Dener ierr = TaoBNKComputeStep(tao, shift, ksp_reason, step_type);CHKERRQ(ierr); 49e0ed867bSAlp Dener if (*ksp_reason < 0) { 50e0ed867bSAlp Dener /* Krylov solver failed to converge so reset the LMVM matrix */ 51*6b591159SAlp Dener ierr = PetscPrintf(PETSC_COMM_SELF, "LMVM reset\n"); 52e0ed867bSAlp Dener ierr = MatLMVMReset(bqnk->B, PETSC_FALSE);CHKERRQ(ierr); 53*6b591159SAlp Dener ierr = MatLMVMUpdate(bqnk->B, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 54e0ed867bSAlp Dener } 55e0ed867bSAlp Dener PetscFunctionReturn(0); 56e0ed867bSAlp Dener } 57e0ed867bSAlp Dener 58*6b591159SAlp Dener PetscErrorCode TaoSetUp_BQNK(Tao tao) 594f4fdda4SAlp Dener { 604f4fdda4SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 614f4fdda4SAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 624f4fdda4SAlp Dener PetscErrorCode ierr; 634f4fdda4SAlp Dener PetscInt n, N; 64*6b591159SAlp Dener PetscBool is_lmvm, is_sym, is_spd; 654f4fdda4SAlp Dener 664f4fdda4SAlp Dener PetscFunctionBegin; 674f4fdda4SAlp Dener ierr = TaoSetUp_BNK(tao);CHKERRQ(ierr); 684f4fdda4SAlp Dener ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr); 694f4fdda4SAlp Dener ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr); 704f4fdda4SAlp Dener ierr = MatSetSizes(bqnk->B, n, n, N, N);CHKERRQ(ierr); 714f4fdda4SAlp Dener ierr = MatLMVMAllocate(bqnk->B,tao->solution,bnk->unprojected_gradient);CHKERRQ(ierr); 724f4fdda4SAlp Dener ierr = PetscObjectBaseTypeCompare((PetscObject)bqnk->B, MATLMVM, &is_lmvm);CHKERRQ(ierr); 734f4fdda4SAlp Dener if (!is_lmvm) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "Matrix must be an LMVM-type"); 744f4fdda4SAlp Dener ierr = MatGetOption(bqnk->B, MAT_SYMMETRIC, &is_sym);CHKERRQ(ierr); 754f4fdda4SAlp Dener if (!is_sym) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix must be symmetric"); 76*6b591159SAlp Dener ierr = MatGetOption(bqnk->B, MAT_SPD, &is_spd);CHKERRQ(ierr); 774f4fdda4SAlp Dener ierr = KSPGetPC(tao->ksp, &bqnk->pc);CHKERRQ(ierr); 784f4fdda4SAlp Dener ierr = PCSetType(bqnk->pc, PCLMVM);CHKERRQ(ierr); 794f4fdda4SAlp Dener ierr = PCLMVMSetMatLMVM(bqnk->pc, bqnk->B);CHKERRQ(ierr); 80*6b591159SAlp Dener if (!bqnk->no_scale && is_spd) { 814f4fdda4SAlp Dener if (!bqnk->Bscale) { 82*6b591159SAlp Dener ierr = MatCreate(PetscObjectComm((PetscObject)bqnk->B), &bqnk->Bscale);CHKERRQ(ierr); 83*6b591159SAlp Dener ierr = MatSetType(bqnk->Bscale, MATLMVMDIAGBRDN);CHKERRQ(ierr); 844f4fdda4SAlp Dener ierr = MatSetOptionsPrefix(bqnk->Bscale, "tao_bqnk_scale_");CHKERRQ(ierr); 85*6b591159SAlp Dener ierr = MatSetFromOptions(bqnk->Bscale);CHKERRQ(ierr); 864f4fdda4SAlp Dener ierr = MatLMVMAllocate(bqnk->Bscale, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 874f4fdda4SAlp Dener } 884f4fdda4SAlp Dener ierr = MatLMVMSetJ0(bqnk->B, bqnk->Bscale);CHKERRQ(ierr); 894f4fdda4SAlp Dener } 904f4fdda4SAlp Dener PetscFunctionReturn(0); 914f4fdda4SAlp Dener } 924f4fdda4SAlp Dener 93e0ed867bSAlp Dener static PetscErrorCode TaoSetFromOptions_BQNK(PetscOptionItems *PetscOptionsObject,Tao tao) 94e0ed867bSAlp Dener { 95e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 96e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 97e0ed867bSAlp Dener PetscErrorCode ierr; 98*6b591159SAlp Dener KSPType ksp_type; 99e0ed867bSAlp Dener 100e0ed867bSAlp Dener PetscFunctionBegin; 1014f4fdda4SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Quasi-Newton-Krylov method for bound constrained optimization");CHKERRQ(ierr); 102*6b591159SAlp Dener ierr = PetscOptionsEList("-tao_bqnk_init_type", "radius initialization type", "", BQNK_INIT, BQNK_INIT_TYPES, BQNK_INIT[bnk->init_type], &bnk->init_type, 0);CHKERRQ(ierr); 103*6b591159SAlp Dener ierr = PetscOptionsEList("-tao_bqnk_update_type", "radius update type", "", BNK_UPDATE, BNK_UPDATE_TYPES, BNK_UPDATE[bnk->update_type], &bnk->update_type, 0);CHKERRQ(ierr); 104*6b591159SAlp Dener ierr = PetscOptionsEList("-tao_bqnk_as_type", "active set estimation method", "", BNK_AS, BNK_AS_TYPES, BNK_AS[bnk->as_type], &bnk->as_type, 0);CHKERRQ(ierr); 105*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_sval", "(developer) Hessian perturbation starting value", "", bnk->sval, &bnk->sval,NULL);CHKERRQ(ierr); 106*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_imin", "(developer) minimum initial Hessian perturbation", "", bnk->imin, &bnk->imin,NULL);CHKERRQ(ierr); 107*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_imax", "(developer) maximum initial Hessian perturbation", "", bnk->imax, &bnk->imax,NULL);CHKERRQ(ierr); 108*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_imfac", "(developer) initial merit factor for Hessian perturbation", "", bnk->imfac, &bnk->imfac,NULL);CHKERRQ(ierr); 109*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmin", "(developer) minimum Hessian perturbation", "", bnk->pmin, &bnk->pmin,NULL);CHKERRQ(ierr); 110*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmax", "(developer) maximum Hessian perturbation", "", bnk->pmax, &bnk->pmax,NULL);CHKERRQ(ierr); 111*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pgfac", "(developer) Hessian perturbation growth factor", "", bnk->pgfac, &bnk->pgfac,NULL);CHKERRQ(ierr); 112*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_psfac", "(developer) Hessian perturbation shrink factor", "", bnk->psfac, &bnk->psfac,NULL);CHKERRQ(ierr); 113*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmgfac", "(developer) merit growth factor for Hessian perturbation", "", bnk->pmgfac, &bnk->pmgfac,NULL);CHKERRQ(ierr); 114*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_pmsfac", "(developer) merit shrink factor for Hessian perturbation", "", bnk->pmsfac, &bnk->pmsfac,NULL);CHKERRQ(ierr); 115*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta1", "(developer) threshold for rejecting step (-tao_bqnk_update_type reduction)", "", bnk->eta1, &bnk->eta1,NULL);CHKERRQ(ierr); 116*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta2", "(developer) threshold for accepting marginal step (-tao_bqnk_update_type reduction)", "", bnk->eta2, &bnk->eta2,NULL);CHKERRQ(ierr); 117*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta3", "(developer) threshold for accepting reasonable step (-tao_bqnk_update_type reduction)", "", bnk->eta3, &bnk->eta3,NULL);CHKERRQ(ierr); 118*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_eta4", "(developer) threshold for accepting good step (-tao_bqnk_update_type reduction)", "", bnk->eta4, &bnk->eta4,NULL);CHKERRQ(ierr); 119*6b591159SAlp 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); 120*6b591159SAlp 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); 121*6b591159SAlp 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); 122*6b591159SAlp 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); 123*6b591159SAlp 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); 124*6b591159SAlp 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); 125*6b591159SAlp 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); 126*6b591159SAlp 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); 127*6b591159SAlp 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); 128*6b591159SAlp 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); 129*6b591159SAlp 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); 130*6b591159SAlp 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); 131*6b591159SAlp 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); 132*6b591159SAlp 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); 133*6b591159SAlp 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); 134*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_mu2", "(developer) threshold for accepting good step (-tao_bqnk_update_type interpolation)", "", bnk->mu2, &bnk->mu2,NULL);CHKERRQ(ierr); 135*6b591159SAlp 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); 136*6b591159SAlp 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); 137*6b591159SAlp 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); 138*6b591159SAlp 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); 139*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_theta", "(developer) trust region interpolation factor (-tao_bqnk_update_type interpolation)", "", bnk->theta, &bnk->theta,NULL);CHKERRQ(ierr); 140*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_min_radius", "(developer) lower bound on initial radius", "", bnk->min_radius, &bnk->min_radius,NULL);CHKERRQ(ierr); 141*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_max_radius", "(developer) upper bound on radius", "", bnk->max_radius, &bnk->max_radius,NULL);CHKERRQ(ierr); 142*6b591159SAlp Dener ierr = PetscOptionsReal("-tao_bqnk_epsilon", "(developer) tolerance used when computing actual and predicted reduction", "", bnk->epsilon, &bnk->epsilon,NULL);CHKERRQ(ierr); 143*6b591159SAlp 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); 144*6b591159SAlp 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); 145*6b591159SAlp 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); 1464f4fdda4SAlp Dener ierr = PetscOptionsBool("-tao_bqnk_no_scale","(developer) disable the diagonal Broyden scaling of the BFGS approximation","",bqnk->no_scale,&bqnk->no_scale,NULL);CHKERRQ(ierr); 1474f4fdda4SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 148*6b591159SAlp Dener ierr = TaoSetFromOptions(bnk->bncg);CHKERRQ(ierr); 149*6b591159SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 150*6b591159SAlp Dener ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 151*6b591159SAlp Dener ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 152*6b591159SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGNASH,&bnk->is_nash);CHKERRQ(ierr); 153*6b591159SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGSTCG,&bnk->is_stcg);CHKERRQ(ierr); 154*6b591159SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGGLTR,&bnk->is_gltr);CHKERRQ(ierr); 155e0ed867bSAlp Dener if (bnk->init_type == BNK_INIT_INTERPOLATION) bnk->init_type = BNK_INIT_DIRECTION; 156e0ed867bSAlp Dener ierr = MatSetFromOptions(bqnk->B);CHKERRQ(ierr); 157e0ed867bSAlp Dener PetscFunctionReturn(0); 158e0ed867bSAlp Dener } 159e0ed867bSAlp Dener 160e0ed867bSAlp Dener static PetscErrorCode TaoView_BQNK(Tao tao, PetscViewer viewer) 161e0ed867bSAlp Dener { 162e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK*)tao->data; 163e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 164e0ed867bSAlp Dener PetscErrorCode ierr; 165e0ed867bSAlp Dener PetscBool isascii; 166e0ed867bSAlp Dener 167e0ed867bSAlp Dener PetscFunctionBegin; 168e0ed867bSAlp Dener ierr = TaoView_BNK(tao, viewer);CHKERRQ(ierr); 169e0ed867bSAlp Dener ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 170e0ed867bSAlp Dener if (isascii) { 171e0ed867bSAlp Dener ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 172e0ed867bSAlp Dener ierr = MatView(bqnk->B, viewer);CHKERRQ(ierr); 173e0ed867bSAlp Dener ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 174e0ed867bSAlp Dener } 175e0ed867bSAlp Dener PetscFunctionReturn(0); 176e0ed867bSAlp Dener } 177e0ed867bSAlp Dener 178e0ed867bSAlp Dener static PetscErrorCode TaoDestroy_BQNK(Tao tao) 179e0ed867bSAlp Dener { 180e0ed867bSAlp Dener TAO_BNK *bnk = (TAO_BNK*)tao->data; 181e0ed867bSAlp Dener TAO_BQNK *bqnk = (TAO_BQNK*)bnk->ctx; 182e0ed867bSAlp Dener PetscErrorCode ierr; 183e0ed867bSAlp Dener 184e0ed867bSAlp Dener PetscFunctionBegin; 1854f4fdda4SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 186cb384e1eSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 187e0ed867bSAlp Dener ierr = MatDestroy(&bqnk->B);CHKERRQ(ierr); 1884f4fdda4SAlp Dener if (!bqnk->no_scale) { 1894f4fdda4SAlp Dener ierr = MatDestroy(&bqnk->Bscale);CHKERRQ(ierr); 1904f4fdda4SAlp Dener } 191e0ed867bSAlp Dener ierr = PetscFree(bnk->ctx);CHKERRQ(ierr); 192e0ed867bSAlp Dener ierr = TaoDestroy_BNK(tao);CHKERRQ(ierr); 193e0ed867bSAlp Dener PetscFunctionReturn(0); 194e0ed867bSAlp Dener } 195e0ed867bSAlp Dener 196e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoCreate_BQNK(Tao tao) 197e0ed867bSAlp Dener { 198e0ed867bSAlp Dener TAO_BNK *bnk; 199e0ed867bSAlp Dener TAO_BQNK *bqnk; 200e0ed867bSAlp Dener PetscErrorCode ierr; 201e0ed867bSAlp Dener 202e0ed867bSAlp Dener PetscFunctionBegin; 203e0ed867bSAlp Dener ierr = TaoCreate_BNK(tao);CHKERRQ(ierr); 204e0ed867bSAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BQNK; 205e0ed867bSAlp Dener tao->ops->destroy = TaoDestroy_BQNK; 206e0ed867bSAlp Dener tao->ops->view = TaoView_BQNK; 2074f4fdda4SAlp Dener tao->ops->setup = TaoSetUp_BQNK; 208e0ed867bSAlp Dener 209e0ed867bSAlp Dener bnk = (TAO_BNK *)tao->data; 210e0ed867bSAlp Dener bnk->computehessian = TaoBQNKComputeHessian; 211e0ed867bSAlp Dener bnk->computestep = TaoBQNKComputeStep; 212e0ed867bSAlp Dener bnk->init_type = BNK_INIT_DIRECTION; 213e0ed867bSAlp Dener 214e0ed867bSAlp Dener ierr = PetscNewLog(tao,&bqnk);CHKERRQ(ierr); 215e0ed867bSAlp Dener bnk->ctx = (void*)bqnk; 2164f4fdda4SAlp Dener bqnk->no_scale = PETSC_FALSE; 217e0ed867bSAlp Dener 218e0ed867bSAlp Dener ierr = MatCreate(PetscObjectComm((PetscObject)tao), &bqnk->B);CHKERRQ(ierr); 219e0ed867bSAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)bqnk->B, (PetscObject)tao, 1);CHKERRQ(ierr); 220e0ed867bSAlp Dener ierr = MatSetOptionsPrefix(bqnk->B, "tao_bqnk_");CHKERRQ(ierr); 221e0ed867bSAlp Dener ierr = MatSetType(bqnk->B, MATLMVMSR1);CHKERRQ(ierr); 222e0ed867bSAlp Dener PetscFunctionReturn(0); 223e0ed867bSAlp Dener }