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; 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 65cd929ea3SAlp Dener ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr); 660ad3a497SAlp Dener ierr = MatLMVMClearJ0(lmP->M);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 93cd929ea3SAlp Dener ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr); 940ad3a497SAlp Dener ierr = MatLMVMClearJ0(lmP->M);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; 145*d5ae2380SAlp Dener PetscBool is_spd; 146a7e14dcfSSatish Balay 147a7e14dcfSSatish Balay PetscFunctionBegin; 148a7e14dcfSSatish Balay /* Existence of tao->solution checked in TaoSetUp() */ 149a7e14dcfSSatish Balay if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); } 150a7e14dcfSSatish Balay if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); } 151a7e14dcfSSatish Balay if (!lmP->D) {ierr = VecDuplicate(tao->solution,&lmP->D);CHKERRQ(ierr); } 152a7e14dcfSSatish Balay if (!lmP->Xold) {ierr = VecDuplicate(tao->solution,&lmP->Xold);CHKERRQ(ierr); } 153a7e14dcfSSatish Balay if (!lmP->Gold) {ierr = VecDuplicate(tao->solution,&lmP->Gold);CHKERRQ(ierr); } 154a7e14dcfSSatish Balay 155a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 156a7e14dcfSSatish Balay ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr); 157a7e14dcfSSatish Balay ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr); 158cd929ea3SAlp Dener ierr = MatSetSizes(lmP->M, n, n, N, N);CHKERRQ(ierr); 159cd929ea3SAlp Dener ierr = MatLMVMAllocate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr); 1600ad3a497SAlp Dener ierr = MatGetOption(lmP->M, MAT_SPD, &is_spd);CHKERRQ(ierr); 1610ad3a497SAlp Dener if (!is_spd) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix is not symmetric positive-definite."); 162a9603a14SPatrick Farrell 163a9603a14SPatrick Farrell /* If the user has set a matrix to solve as the initial H0, set the options prefix here, and set up the KSP */ 164a9603a14SPatrick Farrell if (lmP->H0) { 165cd929ea3SAlp Dener ierr = MatLMVMSetJ0(lmP->M, lmP->H0);CHKERRQ(ierr); 166a9603a14SPatrick Farrell } 167a9603a14SPatrick Farrell 168a7e14dcfSSatish Balay PetscFunctionReturn(0); 169a7e14dcfSSatish Balay } 170a7e14dcfSSatish Balay 171a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 172441846f8SBarry Smith static PetscErrorCode TaoDestroy_LMVM(Tao tao) 173a7e14dcfSSatish Balay { 174a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 175a7e14dcfSSatish Balay PetscErrorCode ierr; 176a7e14dcfSSatish Balay 177a7e14dcfSSatish Balay PetscFunctionBegin; 178a7e14dcfSSatish Balay if (tao->setupcalled) { 179a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Xold);CHKERRQ(ierr); 180a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Gold);CHKERRQ(ierr); 181a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->D);CHKERRQ(ierr); 182a7e14dcfSSatish Balay } 183cd929ea3SAlp Dener ierr = MatDestroy(&lmP->M);CHKERRQ(ierr); 184a9603a14SPatrick Farrell if (lmP->H0) { 185a9603a14SPatrick Farrell ierr = PetscObjectDereference((PetscObject)lmP->H0);CHKERRQ(ierr); 186a9603a14SPatrick Farrell } 187a7e14dcfSSatish Balay ierr = PetscFree(tao->data);CHKERRQ(ierr); 188a9603a14SPatrick Farrell 189a7e14dcfSSatish Balay PetscFunctionReturn(0); 190a7e14dcfSSatish Balay } 191a7e14dcfSSatish Balay 192a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 1934416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_LMVM(PetscOptionItems *PetscOptionsObject,Tao tao) 194a7e14dcfSSatish Balay { 195cd929ea3SAlp Dener TAO_LMVM *lm = (TAO_LMVM *)tao->data; 196a7e14dcfSSatish Balay PetscErrorCode ierr; 197a7e14dcfSSatish Balay 198a7e14dcfSSatish Balay PetscFunctionBegin; 1991a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Limited-memory variable-metric method for unconstrained optimization");CHKERRQ(ierr); 200cd929ea3SAlp Dener ierr = PetscOptionsBool("-tao_lmvm_recycle","enable recycling of the BFGS matrix between subsequent TaoSolve() calls","",lm->recycle,&lm->recycle,NULL);CHKERRQ(ierr); 201114d2d62SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 202cd929ea3SAlp Dener ierr = MatSetFromOptions(lm->M);CHKERRQ(ierr); 203288b7216SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 204a7e14dcfSSatish Balay PetscFunctionReturn(0); 205a7e14dcfSSatish Balay } 206a7e14dcfSSatish Balay 207a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 208441846f8SBarry Smith static PetscErrorCode TaoView_LMVM(Tao tao, PetscViewer viewer) 209a7e14dcfSSatish Balay { 210a7e14dcfSSatish Balay TAO_LMVM *lm = (TAO_LMVM *)tao->data; 211cd929ea3SAlp Dener PetscBool isascii; 2124d6623b4SAlp Dener PetscInt recycled_its; 213a7e14dcfSSatish Balay PetscErrorCode ierr; 214a7e14dcfSSatish Balay 215a7e14dcfSSatish Balay PetscFunctionBegin; 216a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 217a7e14dcfSSatish Balay if (isascii) { 218a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, " Gradient steps: %D\n", lm->grad);CHKERRQ(ierr); 219cd929ea3SAlp Dener if (lm->recycle) { 220288b7216SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Recycle: on\n");CHKERRQ(ierr); 221cd929ea3SAlp Dener recycled_its = lm->bfgs + lm->grad; 2224d6623b4SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Total recycled iterations: %D\n", recycled_its);CHKERRQ(ierr); 223a0bfee83SAlp Dener } 224a7e14dcfSSatish Balay } 225a7e14dcfSSatish Balay PetscFunctionReturn(0); 226a7e14dcfSSatish Balay } 227a7e14dcfSSatish Balay 228a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 229a7e14dcfSSatish Balay 2304aa34175SJason Sarich /*MC 2314aa34175SJason Sarich TAOLMVM - Limited Memory Variable Metric method is a quasi-Newton 2324aa34175SJason Sarich optimization solver for unconstrained minimization. It solves 2334aa34175SJason Sarich the Newton step 2344aa34175SJason Sarich Hkdk = - gk 2354aa34175SJason Sarich 2364aa34175SJason Sarich using an approximation Bk in place of Hk, where Bk is composed using 2374aa34175SJason Sarich the BFGS update formula. A More-Thuente line search is then used 2384aa34175SJason Sarich to computed the steplength in the dk direction 2390ad3a497SAlp Dener 2404aa34175SJason Sarich Options Database Keys: 241cd929ea3SAlp Dener . -tao_lmvm_recycle - enable recycling LMVM updates between TaoSolve() calls 2420ad3a497SAlp Dener . -tao_lmvm_no_scale - (developer) disables diagonal Broyden scaling on the LMVM approximation 2434aa34175SJason Sarich 2441eb8069cSJason Sarich Level: beginner 2454aa34175SJason Sarich M*/ 2464aa34175SJason Sarich 247728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_LMVM(Tao tao) 248a7e14dcfSSatish Balay { 249a7e14dcfSSatish Balay TAO_LMVM *lmP; 2508caf6e8cSBarry Smith const char *morethuente_type = TAOLINESEARCHMT; 251a7e14dcfSSatish Balay PetscErrorCode ierr; 252a7e14dcfSSatish Balay 253a7e14dcfSSatish Balay PetscFunctionBegin; 254a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_LMVM; 255a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_LMVM; 256a7e14dcfSSatish Balay tao->ops->view = TaoView_LMVM; 257a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_LMVM; 258a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_LMVM; 259a7e14dcfSSatish Balay 2603c9e27cfSGeoffrey Irving ierr = PetscNewLog(tao,&lmP);CHKERRQ(ierr); 261a7e14dcfSSatish Balay lmP->D = 0; 262a7e14dcfSSatish Balay lmP->M = 0; 263a7e14dcfSSatish Balay lmP->Xold = 0; 264a7e14dcfSSatish Balay lmP->Gold = 0; 265a9603a14SPatrick Farrell lmP->H0 = NULL; 266cd929ea3SAlp Dener lmP->recycle = PETSC_FALSE; 267a7e14dcfSSatish Balay 268a7e14dcfSSatish Balay tao->data = (void*)lmP; 2696552cf8aSJason Sarich /* Override default settings (unless already changed) */ 2706552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 2000; 2716552cf8aSJason Sarich if (!tao->max_funcs_changed) tao->max_funcs = 4000; 272a7e14dcfSSatish Balay 273a7e14dcfSSatish Balay ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 27463b15415SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 275a7e14dcfSSatish Balay ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 276441846f8SBarry Smith ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 2775d527766SPatrick Farrell ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 278cd929ea3SAlp Dener 279cd929ea3SAlp Dener ierr = KSPInitializePackage();CHKERRQ(ierr); 280cd929ea3SAlp Dener ierr = MatCreate(((PetscObject)tao)->comm, &lmP->M);CHKERRQ(ierr); 281cd929ea3SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)lmP->M, (PetscObject)tao, 1);CHKERRQ(ierr); 28278e4361aSAlp Dener ierr = MatSetType(lmP->M, MATLMVMBFGS);CHKERRQ(ierr); 283cd929ea3SAlp Dener ierr = MatSetOptionsPrefix(lmP->M, "tao_lmvm_");CHKERRQ(ierr); 284a7e14dcfSSatish Balay PetscFunctionReturn(0); 285a7e14dcfSSatish Balay } 28613b46278SAlp Dener 28713b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMSetH0(Tao tao, Mat H0) 28813b46278SAlp Dener { 28913b46278SAlp Dener TAO_LMVM *lmP; 29013b46278SAlp Dener TAO_BLMVM *blmP; 2914f4fdda4SAlp Dener TaoType type; 29213b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 29313b46278SAlp Dener PetscErrorCode ierr; 29413b46278SAlp Dener 29513b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 29613b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 29713b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 29813b46278SAlp Dener 29913b46278SAlp Dener if (is_lmvm) { 30013b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 30113b46278SAlp Dener ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 30213b46278SAlp Dener lmP->H0 = H0; 30313b46278SAlp Dener } else if (is_blmvm) { 30413b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 30513b46278SAlp Dener ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 30613b46278SAlp Dener blmP->H0 = H0; 30713b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 30813b46278SAlp Dener PetscFunctionReturn(0); 30913b46278SAlp Dener } 31013b46278SAlp Dener 31113b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMGetH0(Tao tao, Mat *H0) 31213b46278SAlp Dener { 31313b46278SAlp Dener TAO_LMVM *lmP; 31413b46278SAlp Dener TAO_BLMVM *blmP; 3154f4fdda4SAlp Dener TaoType type; 31613b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 31713b46278SAlp Dener Mat M; 31813b46278SAlp Dener 31913b46278SAlp Dener PetscErrorCode ierr; 32013b46278SAlp Dener 32113b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 32213b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 32313b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 32413b46278SAlp Dener 32513b46278SAlp Dener if (is_lmvm) { 32613b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 32713b46278SAlp Dener M = lmP->M; 32813b46278SAlp Dener } else if (is_blmvm) { 32913b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 33013b46278SAlp Dener M = blmP->M; 33113b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 33213b46278SAlp Dener ierr = MatLMVMGetJ0(M, H0);CHKERRQ(ierr); 33313b46278SAlp Dener PetscFunctionReturn(0); 33413b46278SAlp Dener } 33513b46278SAlp Dener 33613b46278SAlp Dener PETSC_EXTERN PetscErrorCode TaoLMVMGetH0KSP(Tao tao, KSP *ksp) 33713b46278SAlp Dener { 33813b46278SAlp Dener TAO_LMVM *lmP; 33913b46278SAlp Dener TAO_BLMVM *blmP; 3404f4fdda4SAlp Dener TaoType type; 34113b46278SAlp Dener PetscBool is_lmvm, is_blmvm; 34213b46278SAlp Dener Mat M; 34313b46278SAlp Dener PetscErrorCode ierr; 34413b46278SAlp Dener 34513b46278SAlp Dener ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 34613b46278SAlp Dener ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 34713b46278SAlp Dener ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 34813b46278SAlp Dener 34913b46278SAlp Dener if (is_lmvm) { 35013b46278SAlp Dener lmP = (TAO_LMVM *)tao->data; 35113b46278SAlp Dener M = lmP->M; 35213b46278SAlp Dener } else if (is_blmvm) { 35313b46278SAlp Dener blmP = (TAO_BLMVM *)tao->data; 35413b46278SAlp Dener M = blmP->M; 35513b46278SAlp Dener } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 35613b46278SAlp Dener ierr = MatLMVMGetJ0KSP(M, ksp);CHKERRQ(ierr); 35713b46278SAlp Dener PetscFunctionReturn(0); 35813b46278SAlp Dener }