1ba92ff59SBarry Smith #include <petsctaolinesearch.h> 2aaa7dc30SBarry Smith #include <../src/tao/unconstrained/impls/lmvm/lmvm.h> 313b46278SAlp Dener #include <../src/tao/bound/impls/blmvm/blmvm.h> 4a7e14dcfSSatish Balay 5cd929ea3SAlp Dener #define LMVM_STEP_BFGS 0 6cd929ea3SAlp Dener #define LMVM_STEP_GRAD 1 7a7e14dcfSSatish Balay 8441846f8SBarry Smith static PetscErrorCode TaoSolve_LMVM(Tao tao) 9a7e14dcfSSatish Balay { 10a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 11a7e14dcfSSatish Balay PetscReal f, fold, gdx, gnorm; 12a7e14dcfSSatish Balay PetscReal step = 1.0; 13a7e14dcfSSatish Balay PetscErrorCode ierr; 14cd929ea3SAlp Dener PetscInt stepType = LMVM_STEP_GRAD, nupdates; 15e4cb33bbSBarry Smith TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; 16a7e14dcfSSatish Balay 17a7e14dcfSSatish Balay PetscFunctionBegin; 18a7e14dcfSSatish Balay 19a7e14dcfSSatish Balay if (tao->XL || tao->XU || tao->ops->computebounds) { 20a7e14dcfSSatish Balay ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by lmvm algorithm\n");CHKERRQ(ierr); 21a7e14dcfSSatish Balay } 22a7e14dcfSSatish Balay 23a7e14dcfSSatish Balay /* Check convergence criteria */ 24a7e14dcfSSatish Balay ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient);CHKERRQ(ierr); 25a9603a14SPatrick Farrell ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 26a9603a14SPatrick Farrell 2787f595a5SBarry Smith if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 28a7e14dcfSSatish Balay 293ecd9318SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 303ecd9318SAlp Dener ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 313ecd9318SAlp Dener ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr); 323ecd9318SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 333ecd9318SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 34a7e14dcfSSatish Balay 35a7e14dcfSSatish Balay /* Set counter for gradient/reset steps */ 36cd929ea3SAlp Dener if (!lmP->recycle) { 37a7e14dcfSSatish Balay lmP->bfgs = 0; 38a7e14dcfSSatish Balay lmP->grad = 0; 39cd929ea3SAlp Dener ierr = MatLMVMReset(lmP->M, PETSC_FALSE); CHKERRQ(ierr); 40de6ffafeSAlp Dener } 41a7e14dcfSSatish Balay 42a7e14dcfSSatish Balay /* Have not converged; continue with Newton method */ 433ecd9318SAlp Dener while (tao->reason == TAO_CONTINUE_ITERATING) { 44a7e14dcfSSatish Balay /* Compute direction */ 45cd929ea3SAlp Dener if (lmP->H0) { 46cd929ea3SAlp Dener ierr = MatLMVMSetJ0(lmP->M, lmP->H0);CHKERRQ(ierr); 47cd929ea3SAlp Dener stepType = LMVM_STEP_BFGS; 48*0ad3a497SAlp Dener } else if (!lmP->no_scale) { 49*0ad3a497SAlp Dener ierr = MatLMVMSetJ0(lmP->M, lmP->Mscale);CHKERRQ(ierr); 50cd929ea3SAlp Dener } 51a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr); 52cd929ea3SAlp Dener ierr = MatSolve(lmP->M, tao->gradient, lmP->D);CHKERRQ(ierr); 53cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(lmP->M, &nupdates); CHKERRQ(ierr); 54cd929ea3SAlp Dener if (nupdates > 0) stepType = LMVM_STEP_BFGS; 55a7e14dcfSSatish Balay 56a7e14dcfSSatish Balay /* Check for success (descent direction) */ 57a7e14dcfSSatish Balay ierr = VecDot(lmP->D, tao->gradient, &gdx);CHKERRQ(ierr); 58a7e14dcfSSatish Balay if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 59a7e14dcfSSatish Balay /* Step is not descent or direction produced not a number 60a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 61a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 62a7e14dcfSSatish Balay which is guaranteed to be descent 63a7e14dcfSSatish Balay 64a7e14dcfSSatish Balay Use steepest descent direction (scaled) 65a7e14dcfSSatish Balay */ 66a7e14dcfSSatish Balay 67cd929ea3SAlp Dener ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr); 68*0ad3a497SAlp Dener ierr = MatLMVMClearJ0(lmP->M);CHKERRQ(ierr); 69a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 70cd929ea3SAlp Dener ierr = MatSolve(lmP->M,tao->gradient, lmP->D);CHKERRQ(ierr); 71a7e14dcfSSatish Balay 72a7e14dcfSSatish Balay /* On a reset, the direction cannot be not a number; it is a 73a7e14dcfSSatish Balay scaled gradient step. No need to check for this condition. */ 74cd929ea3SAlp Dener stepType = LMVM_STEP_GRAD; 75a7e14dcfSSatish Balay } 76a7e14dcfSSatish Balay ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr); 77a7e14dcfSSatish Balay 78a7e14dcfSSatish Balay /* Perform the linesearch */ 79a7e14dcfSSatish Balay fold = f; 80a7e14dcfSSatish Balay ierr = VecCopy(tao->solution, lmP->Xold);CHKERRQ(ierr); 81a7e14dcfSSatish Balay ierr = VecCopy(tao->gradient, lmP->Gold);CHKERRQ(ierr); 82a7e14dcfSSatish Balay 83a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step,&ls_status);CHKERRQ(ierr); 84a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 85a7e14dcfSSatish Balay 86cd929ea3SAlp Dener if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER && (stepType != LMVM_STEP_GRAD)) { 87a7e14dcfSSatish Balay /* Reset factors and use scaled gradient step */ 88a7e14dcfSSatish Balay f = fold; 89a7e14dcfSSatish Balay ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr); 90a7e14dcfSSatish Balay ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr); 91a7e14dcfSSatish Balay 92a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with BFGS step */ 93a7e14dcfSSatish Balay /* Attempt to use the scaled gradient direction */ 94a7e14dcfSSatish Balay 95cd929ea3SAlp Dener ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr); 96*0ad3a497SAlp Dener ierr = MatLMVMClearJ0(lmP->M);CHKERRQ(ierr); 97a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 98cd929ea3SAlp Dener ierr = MatSolve(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 99a7e14dcfSSatish Balay 100a7e14dcfSSatish Balay /* On a reset, the direction cannot be not a number; it is a 101a7e14dcfSSatish Balay scaled gradient step. No need to check for this condition. */ 102cd929ea3SAlp Dener stepType = LMVM_STEP_GRAD; 103a7e14dcfSSatish Balay ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr); 104a7e14dcfSSatish Balay 105a7e14dcfSSatish Balay /* Perform the linesearch */ 106a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step, &ls_status);CHKERRQ(ierr); 107a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 108a7e14dcfSSatish Balay } 109a7e14dcfSSatish Balay 11087f595a5SBarry Smith if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) { 111a7e14dcfSSatish Balay /* Failed to find an improving point */ 112a7e14dcfSSatish Balay f = fold; 113a7e14dcfSSatish Balay ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr); 114a7e14dcfSSatish Balay ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr); 115a7e14dcfSSatish Balay step = 0.0; 116a7e14dcfSSatish Balay tao->reason = TAO_DIVERGED_LS_FAILURE; 117cd929ea3SAlp Dener } else { 118cd929ea3SAlp Dener /* LS found valid step, so tally up step type */ 119cd929ea3SAlp Dener switch (stepType) { 120cd929ea3SAlp Dener case LMVM_STEP_BFGS: 121cd929ea3SAlp Dener ++lmP->bfgs; 122cd929ea3SAlp Dener break; 123cd929ea3SAlp Dener case LMVM_STEP_GRAD: 124cd929ea3SAlp Dener ++lmP->grad; 125cd929ea3SAlp Dener break; 126cd929ea3SAlp Dener default: 127cd929ea3SAlp Dener break; 128cd929ea3SAlp Dener } 129cd929ea3SAlp Dener /* Compute new gradient norm */ 130cd929ea3SAlp Dener ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 131a7e14dcfSSatish Balay } 132a9603a14SPatrick Farrell 133cd929ea3SAlp Dener /* Check convergence */ 1348931d482SJason Sarich tao->niter++; 1353ecd9318SAlp Dener ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 1363ecd9318SAlp Dener ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr); 1373ecd9318SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 138a7e14dcfSSatish Balay } 139a7e14dcfSSatish Balay PetscFunctionReturn(0); 140a7e14dcfSSatish Balay } 14187f595a5SBarry Smith 142441846f8SBarry Smith static PetscErrorCode TaoSetUp_LMVM(Tao tao) 143a7e14dcfSSatish Balay { 144a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 145a7e14dcfSSatish Balay PetscInt n,N; 146a7e14dcfSSatish Balay PetscErrorCode ierr; 147*0ad3a497SAlp Dener PetscBool is_spd, is_symbrdn; 148a7e14dcfSSatish Balay 149a7e14dcfSSatish Balay PetscFunctionBegin; 150a7e14dcfSSatish Balay /* Existence of tao->solution checked in TaoSetUp() */ 151a7e14dcfSSatish Balay if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); } 152a7e14dcfSSatish Balay if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); } 153a7e14dcfSSatish Balay if (!lmP->D) {ierr = VecDuplicate(tao->solution,&lmP->D);CHKERRQ(ierr); } 154a7e14dcfSSatish Balay if (!lmP->Xold) {ierr = VecDuplicate(tao->solution,&lmP->Xold);CHKERRQ(ierr); } 155a7e14dcfSSatish Balay if (!lmP->Gold) {ierr = VecDuplicate(tao->solution,&lmP->Gold);CHKERRQ(ierr); } 156a7e14dcfSSatish Balay 157a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 158a7e14dcfSSatish Balay ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr); 159a7e14dcfSSatish Balay ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr); 160cd929ea3SAlp Dener ierr = MatSetSizes(lmP->M, n, n, N, N);CHKERRQ(ierr); 161cd929ea3SAlp Dener ierr = MatLMVMAllocate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr); 162*0ad3a497SAlp Dener ierr = MatGetOption(lmP->M, MAT_SPD, &is_spd);CHKERRQ(ierr); 163*0ad3a497SAlp Dener if (!is_spd) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix is not symmetric positive-definite."); 164*0ad3a497SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)lmP->M, MATLMVMSYMBRDN, &is_symbrdn); 165*0ad3a497SAlp Dener if (is_symbrdn) lmP->no_scale = PETSC_TRUE; /* makes no sense to scale L-SymBrdn with SymBrdn diagonal */ 166a9603a14SPatrick Farrell 167a9603a14SPatrick Farrell /* If the user has set a matrix to solve as the initial H0, set the options prefix here, and set up the KSP */ 168a9603a14SPatrick Farrell if (lmP->H0) { 169cd929ea3SAlp Dener ierr = MatLMVMSetJ0(lmP->M, lmP->H0);CHKERRQ(ierr); 170*0ad3a497SAlp Dener } else if (!lmP->no_scale) { 171*0ad3a497SAlp Dener if (!lmP->Mscale) { 172*0ad3a497SAlp Dener ierr = MatCreateLMVMDiagBrdn(PetscObjectComm((PetscObject)lmP->M), n, N, &lmP->Mscale);CHKERRQ(ierr); 173*0ad3a497SAlp Dener ierr = MatSetOptionsPrefix(lmP->Mscale, "tao_lmvm_scale_");CHKERRQ(ierr); 174*0ad3a497SAlp Dener ierr = MatLMVMAllocate(lmP->Mscale, tao->solution, tao->gradient);CHKERRQ(ierr); 175*0ad3a497SAlp Dener } 176*0ad3a497SAlp Dener ierr = MatLMVMSetJ0(lmP->M, lmP->Mscale);CHKERRQ(ierr); 177a9603a14SPatrick Farrell } 178a9603a14SPatrick Farrell 179a7e14dcfSSatish Balay PetscFunctionReturn(0); 180a7e14dcfSSatish Balay } 181a7e14dcfSSatish Balay 182a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 183441846f8SBarry Smith static PetscErrorCode TaoDestroy_LMVM(Tao tao) 184a7e14dcfSSatish Balay { 185a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 186a7e14dcfSSatish Balay PetscErrorCode ierr; 187a7e14dcfSSatish Balay 188a7e14dcfSSatish Balay PetscFunctionBegin; 189a7e14dcfSSatish Balay if (tao->setupcalled) { 190a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Xold);CHKERRQ(ierr); 191a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Gold);CHKERRQ(ierr); 192a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->D);CHKERRQ(ierr); 193a7e14dcfSSatish Balay } 194cd929ea3SAlp Dener ierr = MatDestroy(&lmP->M);CHKERRQ(ierr); 195a9603a14SPatrick Farrell if (lmP->H0) { 196a9603a14SPatrick Farrell ierr = PetscObjectDereference((PetscObject)lmP->H0);CHKERRQ(ierr); 197a9603a14SPatrick Farrell } 198*0ad3a497SAlp Dener if (lmP->Mscale) { 199*0ad3a497SAlp Dener ierr = MatDestroy(&lmP->Mscale);CHKERRQ(ierr); 200*0ad3a497SAlp Dener } 201a7e14dcfSSatish Balay ierr = PetscFree(tao->data);CHKERRQ(ierr); 202a9603a14SPatrick Farrell 203a7e14dcfSSatish Balay PetscFunctionReturn(0); 204a7e14dcfSSatish Balay } 205a7e14dcfSSatish Balay 206a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 2074416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_LMVM(PetscOptionItems *PetscOptionsObject,Tao tao) 208a7e14dcfSSatish Balay { 209cd929ea3SAlp Dener TAO_LMVM *lm = (TAO_LMVM *)tao->data; 210a7e14dcfSSatish Balay PetscErrorCode ierr; 211a7e14dcfSSatish Balay 212a7e14dcfSSatish Balay PetscFunctionBegin; 2131a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Limited-memory variable-metric method for unconstrained optimization");CHKERRQ(ierr); 214cd929ea3SAlp Dener ierr = PetscOptionsBool("-tao_lmvm_recycle","enable recycling of the BFGS matrix between subsequent TaoSolve() calls","",lm->recycle,&lm->recycle,NULL);CHKERRQ(ierr); 215*0ad3a497SAlp Dener ierr = PetscOptionsBool("-tao_lmvm_no_scale","(developer) disable the diagonal Broyden scaling of the BFGS approximation","",lm->no_scale,&lm->no_scale,NULL);CHKERRQ(ierr); 216114d2d62SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 217cd929ea3SAlp Dener ierr = MatSetFromOptions(lm->M);CHKERRQ(ierr); 218288b7216SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 219a7e14dcfSSatish Balay PetscFunctionReturn(0); 220a7e14dcfSSatish Balay } 221a7e14dcfSSatish Balay 222a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 223441846f8SBarry Smith static PetscErrorCode TaoView_LMVM(Tao tao, PetscViewer viewer) 224a7e14dcfSSatish Balay { 225a7e14dcfSSatish Balay TAO_LMVM *lm = (TAO_LMVM *)tao->data; 226cd929ea3SAlp Dener PetscBool isascii; 2274d6623b4SAlp Dener PetscInt recycled_its; 228a7e14dcfSSatish Balay PetscErrorCode ierr; 229a7e14dcfSSatish Balay 230a7e14dcfSSatish Balay PetscFunctionBegin; 231a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 232a7e14dcfSSatish Balay if (isascii) { 233a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, " Gradient steps: %D\n", lm->grad);CHKERRQ(ierr); 234cd929ea3SAlp Dener if (lm->recycle) { 235288b7216SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Recycle: on\n");CHKERRQ(ierr); 236cd929ea3SAlp Dener recycled_its = lm->bfgs + lm->grad; 2374d6623b4SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Total recycled iterations: %D\n", recycled_its);CHKERRQ(ierr); 238a0bfee83SAlp Dener } 239a7e14dcfSSatish Balay } 240a7e14dcfSSatish Balay PetscFunctionReturn(0); 241a7e14dcfSSatish Balay } 242a7e14dcfSSatish Balay 243a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 244a7e14dcfSSatish Balay 2454aa34175SJason Sarich /*MC 2464aa34175SJason Sarich TAOLMVM - Limited Memory Variable Metric method is a quasi-Newton 2474aa34175SJason Sarich optimization solver for unconstrained minimization. It solves 2484aa34175SJason Sarich the Newton step 2494aa34175SJason Sarich Hkdk = - gk 2504aa34175SJason Sarich 2514aa34175SJason Sarich using an approximation Bk in place of Hk, where Bk is composed using 2524aa34175SJason Sarich the BFGS update formula. A More-Thuente line search is then used 2534aa34175SJason Sarich to computed the steplength in the dk direction 254*0ad3a497SAlp Dener 2554aa34175SJason Sarich Options Database Keys: 256cd929ea3SAlp Dener . -tao_lmvm_recycle - enable recycling LMVM updates between TaoSolve() calls 257*0ad3a497SAlp Dener . -tao_lmvm_no_scale - (developer) disables diagonal Broyden scaling on the LMVM approximation 2584aa34175SJason Sarich 2591eb8069cSJason Sarich Level: beginner 2604aa34175SJason Sarich M*/ 2614aa34175SJason Sarich 262728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_LMVM(Tao tao) 263a7e14dcfSSatish Balay { 264a7e14dcfSSatish Balay TAO_LMVM *lmP; 2658caf6e8cSBarry Smith const char *morethuente_type = TAOLINESEARCHMT; 266a7e14dcfSSatish Balay PetscErrorCode ierr; 267a7e14dcfSSatish Balay 268a7e14dcfSSatish Balay PetscFunctionBegin; 269a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_LMVM; 270a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_LMVM; 271a7e14dcfSSatish Balay tao->ops->view = TaoView_LMVM; 272a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_LMVM; 273a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_LMVM; 274a7e14dcfSSatish Balay 2753c9e27cfSGeoffrey Irving ierr = PetscNewLog(tao,&lmP);CHKERRQ(ierr); 276a7e14dcfSSatish Balay lmP->D = 0; 277a7e14dcfSSatish Balay lmP->M = 0; 278a7e14dcfSSatish Balay lmP->Xold = 0; 279a7e14dcfSSatish Balay lmP->Gold = 0; 280a9603a14SPatrick Farrell lmP->H0 = NULL; 281cd929ea3SAlp Dener lmP->recycle = PETSC_FALSE; 282*0ad3a497SAlp Dener lmP->no_scale = PETSC_FALSE; 283a7e14dcfSSatish Balay 284a7e14dcfSSatish Balay tao->data = (void*)lmP; 2856552cf8aSJason Sarich /* Override default settings (unless already changed) */ 2866552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 2000; 2876552cf8aSJason Sarich if (!tao->max_funcs_changed) tao->max_funcs = 4000; 288a7e14dcfSSatish Balay 289a7e14dcfSSatish Balay ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 29063b15415SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 291a7e14dcfSSatish Balay ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 292441846f8SBarry Smith ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 2935d527766SPatrick Farrell ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 294cd929ea3SAlp Dener 295cd929ea3SAlp Dener ierr = KSPInitializePackage();CHKERRQ(ierr); 296cd929ea3SAlp Dener ierr = MatCreate(((PetscObject)tao)->comm, &lmP->M);CHKERRQ(ierr); 297cd929ea3SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)lmP->M, (PetscObject)tao, 1);CHKERRQ(ierr); 29878e4361aSAlp Dener ierr = MatSetType(lmP->M, MATLMVMBFGS);CHKERRQ(ierr); 299cd929ea3SAlp Dener ierr = MatSetOptionsPrefix(lmP->M, "tao_lmvm_");CHKERRQ(ierr); 300a7e14dcfSSatish Balay PetscFunctionReturn(0); 301a7e14dcfSSatish Balay } 30213b46278SAlp Dener 30313b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMSetH0(Tao tao, Mat H0) 30413b46278SAlp Dener { 30513b46278SAlp Dener TAO_LMVM *lmP; 30613b46278SAlp Dener TAO_BLMVM *blmP; 30713b46278SAlp Dener const TaoType type; 30813b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 30913b46278SAlp Dener PetscErrorCode ierr; 31013b46278SAlp Dener 31113b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 31213b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 31313b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 31413b46278SAlp Dener 31513b46278SAlp Dener if (is_lmvm) { 31613b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 31713b46278SAlp Dener ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 31813b46278SAlp Dener lmP->H0 = H0; 31913b46278SAlp Dener } else if (is_blmvm) { 32013b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 32113b46278SAlp Dener ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 32213b46278SAlp Dener blmP->H0 = H0; 32313b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 32413b46278SAlp Dener PetscFunctionReturn(0); 32513b46278SAlp Dener } 32613b46278SAlp Dener 32713b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMGetH0(Tao tao, Mat *H0) 32813b46278SAlp Dener { 32913b46278SAlp Dener TAO_LMVM *lmP; 33013b46278SAlp Dener TAO_BLMVM *blmP; 33113b46278SAlp Dener const TaoType type; 33213b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 33313b46278SAlp Dener Mat M; 33413b46278SAlp Dener 33513b46278SAlp Dener PetscErrorCode ierr; 33613b46278SAlp Dener 33713b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 33813b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 33913b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 34013b46278SAlp Dener 34113b46278SAlp Dener if (is_lmvm) { 34213b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 34313b46278SAlp Dener M = lmP->M; 34413b46278SAlp Dener } else if (is_blmvm) { 34513b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 34613b46278SAlp Dener M = blmP->M; 34713b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 34813b46278SAlp Dener ierr = MatLMVMGetJ0(M, H0);CHKERRQ(ierr); 34913b46278SAlp Dener PetscFunctionReturn(0); 35013b46278SAlp Dener } 35113b46278SAlp Dener 35213b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMGetH0KSP(Tao tao, KSP *ksp) 35313b46278SAlp Dener { 35413b46278SAlp Dener TAO_LMVM *lmP; 35513b46278SAlp Dener TAO_BLMVM *blmP; 35613b46278SAlp Dener const TaoType type; 35713b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 35813b46278SAlp Dener Mat M; 35913b46278SAlp Dener PetscErrorCode ierr; 36013b46278SAlp Dener 36113b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 36213b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 36313b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 36413b46278SAlp Dener 36513b46278SAlp Dener if (is_lmvm) { 36613b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 36713b46278SAlp Dener M = lmP->M; 36813b46278SAlp Dener } else if (is_blmvm) { 36913b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 37013b46278SAlp Dener M = blmP->M; 37113b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 37213b46278SAlp Dener ierr = MatLMVMGetJ0KSP(M, ksp);CHKERRQ(ierr); 37313b46278SAlp Dener PetscFunctionReturn(0); 37413b46278SAlp Dener }