1ba92ff59SBarry Smith #include <petsctaolinesearch.h> 2aaa7dc30SBarry Smith #include <../src/tao/unconstrained/impls/lmvm/lmvm.h> 3*13b46278SAlp 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; 48cd929ea3SAlp Dener } 49a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr); 50cd929ea3SAlp Dener ierr = MatSolve(lmP->M, tao->gradient, lmP->D);CHKERRQ(ierr); 51cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(lmP->M, &nupdates); CHKERRQ(ierr); 52cd929ea3SAlp Dener if (nupdates > 0) stepType = LMVM_STEP_BFGS; 53a7e14dcfSSatish Balay 54a7e14dcfSSatish Balay /* Check for success (descent direction) */ 55a7e14dcfSSatish Balay ierr = VecDot(lmP->D, tao->gradient, &gdx);CHKERRQ(ierr); 56a7e14dcfSSatish Balay if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 57a7e14dcfSSatish Balay /* Step is not descent or direction produced not a number 58a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 59a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 60a7e14dcfSSatish Balay which is guaranteed to be descent 61a7e14dcfSSatish Balay 62a7e14dcfSSatish Balay Use steepest descent direction (scaled) 63a7e14dcfSSatish Balay */ 64a7e14dcfSSatish Balay 65b2d8c577SAlp Dener ierr = MatLMVMResetJ0(lmP->M);CHKERRQ(ierr); 66cd929ea3SAlp Dener ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr); 67a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 68cd929ea3SAlp Dener ierr = MatSolve(lmP->M,tao->gradient, lmP->D);CHKERRQ(ierr); 69a7e14dcfSSatish Balay 70a7e14dcfSSatish Balay /* On a reset, the direction cannot be not a number; it is a 71a7e14dcfSSatish Balay scaled gradient step. No need to check for this condition. */ 72cd929ea3SAlp Dener stepType = LMVM_STEP_GRAD; 73a7e14dcfSSatish Balay } 74a7e14dcfSSatish Balay ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr); 75a7e14dcfSSatish Balay 76a7e14dcfSSatish Balay /* Perform the linesearch */ 77a7e14dcfSSatish Balay fold = f; 78a7e14dcfSSatish Balay ierr = VecCopy(tao->solution, lmP->Xold);CHKERRQ(ierr); 79a7e14dcfSSatish Balay ierr = VecCopy(tao->gradient, lmP->Gold);CHKERRQ(ierr); 80a7e14dcfSSatish Balay 81a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step,&ls_status);CHKERRQ(ierr); 82a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 83a7e14dcfSSatish Balay 84cd929ea3SAlp Dener if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER && (stepType != LMVM_STEP_GRAD)) { 85a7e14dcfSSatish Balay /* Reset factors and use scaled gradient step */ 86a7e14dcfSSatish Balay f = fold; 87a7e14dcfSSatish Balay ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr); 88a7e14dcfSSatish Balay ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr); 89a7e14dcfSSatish Balay 90a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with BFGS step */ 91a7e14dcfSSatish Balay /* Attempt to use the scaled gradient direction */ 92a7e14dcfSSatish Balay 93b2d8c577SAlp Dener ierr = MatLMVMResetJ0(lmP->M);CHKERRQ(ierr); 94cd929ea3SAlp Dener ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr); 95a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 96cd929ea3SAlp Dener ierr = MatSolve(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 97a7e14dcfSSatish Balay 98a7e14dcfSSatish Balay /* On a reset, the direction cannot be not a number; it is a 99a7e14dcfSSatish Balay scaled gradient step. No need to check for this condition. */ 100cd929ea3SAlp Dener stepType = LMVM_STEP_GRAD; 101a7e14dcfSSatish Balay ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr); 102a7e14dcfSSatish Balay 103a7e14dcfSSatish Balay /* Perform the linesearch */ 104a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step, &ls_status);CHKERRQ(ierr); 105a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 106a7e14dcfSSatish Balay } 107a7e14dcfSSatish Balay 10887f595a5SBarry Smith if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) { 109a7e14dcfSSatish Balay /* Failed to find an improving point */ 110a7e14dcfSSatish Balay f = fold; 111a7e14dcfSSatish Balay ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr); 112a7e14dcfSSatish Balay ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr); 113a7e14dcfSSatish Balay step = 0.0; 114a7e14dcfSSatish Balay tao->reason = TAO_DIVERGED_LS_FAILURE; 115cd929ea3SAlp Dener } else { 116cd929ea3SAlp Dener /* LS found valid step, so tally up step type */ 117cd929ea3SAlp Dener switch (stepType) { 118cd929ea3SAlp Dener case LMVM_STEP_BFGS: 119cd929ea3SAlp Dener ++lmP->bfgs; 120cd929ea3SAlp Dener break; 121cd929ea3SAlp Dener case LMVM_STEP_GRAD: 122cd929ea3SAlp Dener ++lmP->grad; 123cd929ea3SAlp Dener break; 124cd929ea3SAlp Dener default: 125cd929ea3SAlp Dener break; 126cd929ea3SAlp Dener } 127cd929ea3SAlp Dener /* Compute new gradient norm */ 128cd929ea3SAlp Dener ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 129a7e14dcfSSatish Balay } 130a9603a14SPatrick Farrell 131cd929ea3SAlp Dener /* Check convergence */ 1328931d482SJason Sarich tao->niter++; 1333ecd9318SAlp Dener ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 1343ecd9318SAlp Dener ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr); 1353ecd9318SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 136a7e14dcfSSatish Balay } 137a7e14dcfSSatish Balay PetscFunctionReturn(0); 138a7e14dcfSSatish Balay } 13987f595a5SBarry Smith 140441846f8SBarry Smith static PetscErrorCode TaoSetUp_LMVM(Tao tao) 141a7e14dcfSSatish Balay { 142a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 143a7e14dcfSSatish Balay PetscInt n,N; 144a7e14dcfSSatish Balay PetscErrorCode ierr; 145a7e14dcfSSatish Balay 146a7e14dcfSSatish Balay PetscFunctionBegin; 147a7e14dcfSSatish Balay /* Existence of tao->solution checked in TaoSetUp() */ 148a7e14dcfSSatish Balay if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); } 149a7e14dcfSSatish Balay if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); } 150a7e14dcfSSatish Balay if (!lmP->D) {ierr = VecDuplicate(tao->solution,&lmP->D);CHKERRQ(ierr); } 151a7e14dcfSSatish Balay if (!lmP->Xold) {ierr = VecDuplicate(tao->solution,&lmP->Xold);CHKERRQ(ierr); } 152a7e14dcfSSatish Balay if (!lmP->Gold) {ierr = VecDuplicate(tao->solution,&lmP->Gold);CHKERRQ(ierr); } 153a7e14dcfSSatish Balay 154a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 155a7e14dcfSSatish Balay ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr); 156a7e14dcfSSatish Balay ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr); 157cd929ea3SAlp Dener ierr = MatSetSizes(lmP->M, n, n, N, N);CHKERRQ(ierr); 158cd929ea3SAlp Dener ierr = MatLMVMAllocate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr); 159a9603a14SPatrick Farrell 160a9603a14SPatrick Farrell /* If the user has set a matrix to solve as the initial H0, set the options prefix here, and set up the KSP */ 161a9603a14SPatrick Farrell if (lmP->H0) { 162cd929ea3SAlp Dener ierr = MatLMVMSetJ0(lmP->M, lmP->H0);CHKERRQ(ierr); 163a9603a14SPatrick Farrell } 164a9603a14SPatrick Farrell 165a7e14dcfSSatish Balay PetscFunctionReturn(0); 166a7e14dcfSSatish Balay } 167a7e14dcfSSatish Balay 168a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 169441846f8SBarry Smith static PetscErrorCode TaoDestroy_LMVM(Tao tao) 170a7e14dcfSSatish Balay { 171a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 172a7e14dcfSSatish Balay PetscErrorCode ierr; 173a7e14dcfSSatish Balay 174a7e14dcfSSatish Balay PetscFunctionBegin; 175a7e14dcfSSatish Balay if (tao->setupcalled) { 176a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Xold);CHKERRQ(ierr); 177a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Gold);CHKERRQ(ierr); 178a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->D);CHKERRQ(ierr); 179a7e14dcfSSatish Balay } 180cd929ea3SAlp Dener ierr = MatDestroy(&lmP->M);CHKERRQ(ierr); 181a9603a14SPatrick Farrell if (lmP->H0) { 182a9603a14SPatrick Farrell ierr = PetscObjectDereference((PetscObject)lmP->H0);CHKERRQ(ierr); 183a9603a14SPatrick Farrell } 184a7e14dcfSSatish Balay ierr = PetscFree(tao->data);CHKERRQ(ierr); 185a9603a14SPatrick Farrell 186a7e14dcfSSatish Balay PetscFunctionReturn(0); 187a7e14dcfSSatish Balay } 188a7e14dcfSSatish Balay 189a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 1904416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_LMVM(PetscOptionItems *PetscOptionsObject,Tao tao) 191a7e14dcfSSatish Balay { 192cd929ea3SAlp Dener TAO_LMVM *lm = (TAO_LMVM *)tao->data; 193a7e14dcfSSatish Balay PetscErrorCode ierr; 194a7e14dcfSSatish Balay 195a7e14dcfSSatish Balay PetscFunctionBegin; 1961a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Limited-memory variable-metric method for unconstrained optimization");CHKERRQ(ierr); 197cd929ea3SAlp Dener ierr = PetscOptionsBool("-tao_lmvm_recycle","enable recycling of the BFGS matrix between subsequent TaoSolve() calls","",lm->recycle,&lm->recycle,NULL);CHKERRQ(ierr); 198114d2d62SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 199cd929ea3SAlp Dener ierr = MatSetFromOptions(lm->M);CHKERRQ(ierr); 200288b7216SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 201a7e14dcfSSatish Balay PetscFunctionReturn(0); 202a7e14dcfSSatish Balay } 203a7e14dcfSSatish Balay 204a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 205441846f8SBarry Smith static PetscErrorCode TaoView_LMVM(Tao tao, PetscViewer viewer) 206a7e14dcfSSatish Balay { 207a7e14dcfSSatish Balay TAO_LMVM *lm = (TAO_LMVM *)tao->data; 208cd929ea3SAlp Dener PetscBool isascii; 2094d6623b4SAlp Dener PetscInt recycled_its; 210a7e14dcfSSatish Balay PetscErrorCode ierr; 211a7e14dcfSSatish Balay 212a7e14dcfSSatish Balay PetscFunctionBegin; 213a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 214a7e14dcfSSatish Balay if (isascii) { 215a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, " Gradient steps: %D\n", lm->grad);CHKERRQ(ierr); 216cd929ea3SAlp Dener if (lm->recycle) { 217288b7216SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Recycle: on\n");CHKERRQ(ierr); 218cd929ea3SAlp Dener recycled_its = lm->bfgs + lm->grad; 2194d6623b4SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Total recycled iterations: %D\n", recycled_its);CHKERRQ(ierr); 220a0bfee83SAlp Dener } 221a7e14dcfSSatish Balay } 222a7e14dcfSSatish Balay PetscFunctionReturn(0); 223a7e14dcfSSatish Balay } 224a7e14dcfSSatish Balay 225a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 226a7e14dcfSSatish Balay 2274aa34175SJason Sarich /*MC 2284aa34175SJason Sarich TAOLMVM - Limited Memory Variable Metric method is a quasi-Newton 2294aa34175SJason Sarich optimization solver for unconstrained minimization. It solves 2304aa34175SJason Sarich the Newton step 2314aa34175SJason Sarich Hkdk = - gk 2324aa34175SJason Sarich 2334aa34175SJason Sarich using an approximation Bk in place of Hk, where Bk is composed using 2344aa34175SJason Sarich the BFGS update formula. A More-Thuente line search is then used 2354aa34175SJason Sarich to computed the steplength in the dk direction 2364aa34175SJason Sarich Options Database Keys: 237cd929ea3SAlp Dener . -tao_lmvm_recycle - enable recycling LMVM updates between TaoSolve() calls 2384aa34175SJason Sarich 2391eb8069cSJason Sarich Level: beginner 2404aa34175SJason Sarich M*/ 2414aa34175SJason Sarich 242728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_LMVM(Tao tao) 243a7e14dcfSSatish Balay { 244a7e14dcfSSatish Balay TAO_LMVM *lmP; 2458caf6e8cSBarry Smith const char *morethuente_type = TAOLINESEARCHMT; 246a7e14dcfSSatish Balay PetscErrorCode ierr; 247a7e14dcfSSatish Balay 248a7e14dcfSSatish Balay PetscFunctionBegin; 249a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_LMVM; 250a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_LMVM; 251a7e14dcfSSatish Balay tao->ops->view = TaoView_LMVM; 252a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_LMVM; 253a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_LMVM; 254a7e14dcfSSatish Balay 2553c9e27cfSGeoffrey Irving ierr = PetscNewLog(tao,&lmP);CHKERRQ(ierr); 256a7e14dcfSSatish Balay lmP->D = 0; 257a7e14dcfSSatish Balay lmP->M = 0; 258a7e14dcfSSatish Balay lmP->Xold = 0; 259a7e14dcfSSatish Balay lmP->Gold = 0; 260a9603a14SPatrick Farrell lmP->H0 = NULL; 261cd929ea3SAlp Dener lmP->recycle = PETSC_FALSE; 262a7e14dcfSSatish Balay 263a7e14dcfSSatish Balay tao->data = (void*)lmP; 2646552cf8aSJason Sarich /* Override default settings (unless already changed) */ 2656552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 2000; 2666552cf8aSJason Sarich if (!tao->max_funcs_changed) tao->max_funcs = 4000; 267a7e14dcfSSatish Balay 268a7e14dcfSSatish Balay ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 26963b15415SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 270a7e14dcfSSatish Balay ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 271441846f8SBarry Smith ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 2725d527766SPatrick Farrell ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 273cd929ea3SAlp Dener 274cd929ea3SAlp Dener ierr = KSPInitializePackage();CHKERRQ(ierr); 275cd929ea3SAlp Dener ierr = MatCreate(((PetscObject)tao)->comm, &lmP->M);CHKERRQ(ierr); 276cd929ea3SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)lmP->M, (PetscObject)tao, 1);CHKERRQ(ierr); 27778e4361aSAlp Dener ierr = MatSetType(lmP->M, MATLMVMBFGS);CHKERRQ(ierr); 278cd929ea3SAlp Dener ierr = MatSetOptionsPrefix(lmP->M, "tao_lmvm_");CHKERRQ(ierr); 279a7e14dcfSSatish Balay PetscFunctionReturn(0); 280a7e14dcfSSatish Balay } 281*13b46278SAlp Dener 282*13b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMSetH0(Tao tao, Mat H0) 283*13b46278SAlp Dener { 284*13b46278SAlp Dener TAO_LMVM *lmP; 285*13b46278SAlp Dener TAO_BLMVM *blmP; 286*13b46278SAlp Dener const TaoType type; 287*13b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 288*13b46278SAlp Dener PetscErrorCode ierr; 289*13b46278SAlp Dener 290*13b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 291*13b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 292*13b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 293*13b46278SAlp Dener 294*13b46278SAlp Dener if (is_lmvm) { 295*13b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 296*13b46278SAlp Dener ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 297*13b46278SAlp Dener lmP->H0 = H0; 298*13b46278SAlp Dener } else if (is_blmvm) { 299*13b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 300*13b46278SAlp Dener ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 301*13b46278SAlp Dener blmP->H0 = H0; 302*13b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 303*13b46278SAlp Dener PetscFunctionReturn(0); 304*13b46278SAlp Dener } 305*13b46278SAlp Dener 306*13b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMGetH0(Tao tao, Mat *H0) 307*13b46278SAlp Dener { 308*13b46278SAlp Dener TAO_LMVM *lmP; 309*13b46278SAlp Dener TAO_BLMVM *blmP; 310*13b46278SAlp Dener const TaoType type; 311*13b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 312*13b46278SAlp Dener Mat M; 313*13b46278SAlp Dener 314*13b46278SAlp Dener PetscErrorCode ierr; 315*13b46278SAlp Dener 316*13b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 317*13b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 318*13b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 319*13b46278SAlp Dener 320*13b46278SAlp Dener if (is_lmvm) { 321*13b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 322*13b46278SAlp Dener M = lmP->M; 323*13b46278SAlp Dener } else if (is_blmvm) { 324*13b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 325*13b46278SAlp Dener M = blmP->M; 326*13b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 327*13b46278SAlp Dener ierr = MatLMVMGetJ0(M, H0);CHKERRQ(ierr); 328*13b46278SAlp Dener PetscFunctionReturn(0); 329*13b46278SAlp Dener } 330*13b46278SAlp Dener 331*13b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMGetH0KSP(Tao tao, KSP *ksp) 332*13b46278SAlp Dener { 333*13b46278SAlp Dener TAO_LMVM *lmP; 334*13b46278SAlp Dener TAO_BLMVM *blmP; 335*13b46278SAlp Dener const TaoType type; 336*13b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 337*13b46278SAlp Dener Mat M; 338*13b46278SAlp Dener PetscErrorCode ierr; 339*13b46278SAlp Dener 340*13b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 341*13b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 342*13b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 343*13b46278SAlp Dener 344*13b46278SAlp Dener if (is_lmvm) { 345*13b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 346*13b46278SAlp Dener M = lmP->M; 347*13b46278SAlp Dener } else if (is_blmvm) { 348*13b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 349*13b46278SAlp Dener M = blmP->M; 350*13b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 351*13b46278SAlp Dener ierr = MatLMVMGetJ0KSP(M, ksp);CHKERRQ(ierr); 352*13b46278SAlp Dener PetscFunctionReturn(0); 353*13b46278SAlp Dener }