xref: /petsc/src/tao/bound/impls/bqnk/bqnk.c (revision e0ed867b6c64a799ff0332d58c8126f3e917b638)
1*e0ed867bSAlp Dener #include <../src/tao/bound/impls/bqnk/bqnk.h>
2*e0ed867bSAlp Dener #include <petscksp.h>
3*e0ed867bSAlp Dener 
4*e0ed867bSAlp Dener /* Routine for computing the approximate quasi-Newton Hessian */
5*e0ed867bSAlp Dener 
6*e0ed867bSAlp Dener static PetscErrorCode TaoBQNKComputeHessian(Tao tao)
7*e0ed867bSAlp Dener {
8*e0ed867bSAlp Dener   TAO_BNK        *bnk = (TAO_BNK *)tao->data;
9*e0ed867bSAlp Dener   TAO_BQNK       *bqnk = (TAO_BQNK*)bnk->ctx;
10*e0ed867bSAlp Dener   PetscErrorCode ierr;
11*e0ed867bSAlp Dener 
12*e0ed867bSAlp Dener   PetscFunctionBegin;
13*e0ed867bSAlp Dener   /* Alias the LMVM matrix into the TAO hessian */
14*e0ed867bSAlp Dener   if (tao->hessian) {
15*e0ed867bSAlp Dener     ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr);
16*e0ed867bSAlp Dener   }
17*e0ed867bSAlp Dener   if (tao->hessian_pre) {
18*e0ed867bSAlp Dener     ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr);
19*e0ed867bSAlp Dener   }
20*e0ed867bSAlp Dener   ierr = PetscObjectReference((PetscObject)bqnk->B);CHKERRQ(ierr);
21*e0ed867bSAlp Dener   tao->hessian = bqnk->B;
22*e0ed867bSAlp Dener   ierr = PetscObjectReference((PetscObject)bqnk->B);CHKERRQ(ierr);
23*e0ed867bSAlp Dener   tao->hessian_pre = bqnk->B;
24*e0ed867bSAlp Dener   /* Update the Hessian with the latest solution */
25*e0ed867bSAlp Dener   ierr = MatLMVMUpdate(tao->hessian, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr);
26*e0ed867bSAlp Dener   ierr = MatLMVMResetShift(tao->hessian);CHKERRQ(ierr);
27*e0ed867bSAlp Dener   /* Prepare the reduced sub-matrices for the inactive set */
28*e0ed867bSAlp Dener   if (bnk->active_idx) {
29*e0ed867bSAlp Dener     ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr);
30*e0ed867bSAlp Dener     ierr = MatCreateSubMatrixVirtual(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, &bnk->H_inactive);CHKERRQ(ierr);
31*e0ed867bSAlp Dener   } else {
32*e0ed867bSAlp Dener     ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr);
33*e0ed867bSAlp Dener     ierr = PetscObjectReference((PetscObject)tao->hessian);CHKERRQ(ierr);
34*e0ed867bSAlp Dener     bnk->H_inactive = tao->hessian;
35*e0ed867bSAlp Dener   }
36*e0ed867bSAlp Dener   bnk->Hpre_inactive = bnk->H_inactive;
37*e0ed867bSAlp Dener   PetscFunctionReturn(0);
38*e0ed867bSAlp Dener }
39*e0ed867bSAlp Dener 
40*e0ed867bSAlp Dener static PetscErrorCode TaoBQNKComputeStep(Tao tao, PetscBool shift, KSPConvergedReason *ksp_reason)
41*e0ed867bSAlp Dener {
42*e0ed867bSAlp Dener   TAO_BNK        *bnk = (TAO_BNK *)tao->data;
43*e0ed867bSAlp Dener   TAO_BQNK       *bqnk = (TAO_BQNK*)bnk->ctx;
44*e0ed867bSAlp Dener   PetscErrorCode ierr;
45*e0ed867bSAlp Dener 
46*e0ed867bSAlp Dener   PetscFunctionBegin;
47*e0ed867bSAlp Dener   ierr = TaoBNKComputeStep(tao, shift, ksp_reason);CHKERRQ(ierr);
48*e0ed867bSAlp Dener   if (*ksp_reason < 0) {
49*e0ed867bSAlp Dener     /* Krylov solver failed to converge so reset the LMVM matrix */
50*e0ed867bSAlp Dener     ierr = MatLMVMReset(bqnk->B, PETSC_FALSE);CHKERRQ(ierr);
51*e0ed867bSAlp Dener   }
52*e0ed867bSAlp Dener   PetscFunctionReturn(0);
53*e0ed867bSAlp Dener }
54*e0ed867bSAlp Dener 
55*e0ed867bSAlp Dener static PetscErrorCode TaoSetFromOptions_BQNK(PetscOptionItems *PetscOptionsObject, Tao tao)
56*e0ed867bSAlp Dener {
57*e0ed867bSAlp Dener   TAO_BNK        *bnk = (TAO_BNK*)tao->data;
58*e0ed867bSAlp Dener   TAO_BQNK       *bqnk = (TAO_BQNK*)bnk->ctx;
59*e0ed867bSAlp Dener   PetscErrorCode ierr;
60*e0ed867bSAlp Dener   PC             pc;
61*e0ed867bSAlp Dener   PetscBool      is_lmvm, is_sym;
62*e0ed867bSAlp Dener 
63*e0ed867bSAlp Dener   PetscFunctionBegin;
64*e0ed867bSAlp Dener   ierr = TaoSetFromOptions_BNK(PetscOptionsObject, tao);CHKERRQ(ierr);
65*e0ed867bSAlp Dener   /* Make sure the interpolation method is disabled for trust region initialization */
66*e0ed867bSAlp Dener   if (bnk->init_type == BNK_INIT_INTERPOLATION) bnk->init_type = BNK_INIT_DIRECTION;
67*e0ed867bSAlp Dener   /* Make sure the KSP solver is a CG method and the preconditioner is disabled */
68*e0ed867bSAlp Dener   if (!bnk->is_nash && !bnk->is_stcg && !bnk->is_gltr) SETERRQ(PETSC_COMM_SELF,1,"Must use a trust-region CG method for KSP (KSPNASH, KSPSTCG, KSPGLTR)");
69*e0ed867bSAlp Dener   ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr);
70*e0ed867bSAlp Dener   ierr = PCSetType(pc, PCNONE);CHKERRQ(ierr);
71*e0ed867bSAlp Dener   /* Read mat options and check type and properties */
72*e0ed867bSAlp Dener   ierr = MatSetFromOptions(bqnk->B);CHKERRQ(ierr);
73*e0ed867bSAlp Dener   ierr = PetscObjectBaseTypeCompare((PetscObject)bqnk->B, MATLMVM, &is_lmvm);CHKERRQ(ierr);
74*e0ed867bSAlp Dener   if (!is_lmvm) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "Matrix must be an LMVM-type");
75*e0ed867bSAlp Dener   ierr = MatGetOption(bqnk->B, MAT_SYMMETRIC, &is_sym);CHKERRQ(ierr);
76*e0ed867bSAlp Dener   if (!is_sym) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix must be symmetric");
77*e0ed867bSAlp Dener   PetscFunctionReturn(0);
78*e0ed867bSAlp Dener }
79*e0ed867bSAlp Dener 
80*e0ed867bSAlp Dener static PetscErrorCode TaoView_BQNK(Tao tao, PetscViewer viewer)
81*e0ed867bSAlp Dener {
82*e0ed867bSAlp Dener   TAO_BNK        *bnk = (TAO_BNK*)tao->data;
83*e0ed867bSAlp Dener   TAO_BQNK       *bqnk = (TAO_BQNK*)bnk->ctx;
84*e0ed867bSAlp Dener   PetscErrorCode ierr;
85*e0ed867bSAlp Dener   PetscBool      isascii;
86*e0ed867bSAlp Dener 
87*e0ed867bSAlp Dener   PetscFunctionBegin;
88*e0ed867bSAlp Dener   ierr = TaoView_BNK(tao, viewer);CHKERRQ(ierr);
89*e0ed867bSAlp Dener   PetscFunctionBegin;
90*e0ed867bSAlp Dener   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
91*e0ed867bSAlp Dener   if (isascii) {
92*e0ed867bSAlp Dener     ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
93*e0ed867bSAlp Dener     ierr = MatView(bqnk->B, viewer);CHKERRQ(ierr);
94*e0ed867bSAlp Dener     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
95*e0ed867bSAlp Dener   }
96*e0ed867bSAlp Dener   PetscFunctionReturn(0);
97*e0ed867bSAlp Dener }
98*e0ed867bSAlp Dener 
99*e0ed867bSAlp Dener static PetscErrorCode TaoDestroy_BQNK(Tao tao)
100*e0ed867bSAlp Dener {
101*e0ed867bSAlp Dener   TAO_BNK        *bnk = (TAO_BNK*)tao->data;
102*e0ed867bSAlp Dener   TAO_BQNK       *bqnk = (TAO_BQNK*)bnk->ctx;
103*e0ed867bSAlp Dener   PetscErrorCode ierr;
104*e0ed867bSAlp Dener 
105*e0ed867bSAlp Dener   PetscFunctionBegin;
106*e0ed867bSAlp Dener   ierr = MatDestroy(&bqnk->B);CHKERRQ(ierr);
107*e0ed867bSAlp Dener   ierr = PetscFree(bnk->ctx);CHKERRQ(ierr);
108*e0ed867bSAlp Dener   ierr = TaoDestroy_BNK(tao);CHKERRQ(ierr);
109*e0ed867bSAlp Dener   PetscFunctionReturn(0);
110*e0ed867bSAlp Dener }
111*e0ed867bSAlp Dener 
112*e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoCreate_BQNK(Tao tao)
113*e0ed867bSAlp Dener {
114*e0ed867bSAlp Dener   TAO_BNK        *bnk;
115*e0ed867bSAlp Dener   TAO_BQNK       *bqnk;
116*e0ed867bSAlp Dener   PetscErrorCode ierr;
117*e0ed867bSAlp Dener 
118*e0ed867bSAlp Dener   PetscFunctionBegin;
119*e0ed867bSAlp Dener   ierr = TaoCreate_BNK(tao);CHKERRQ(ierr);
120*e0ed867bSAlp Dener   tao->ops->setfromoptions = TaoSetFromOptions_BQNK;
121*e0ed867bSAlp Dener   tao->ops->destroy = TaoDestroy_BQNK;
122*e0ed867bSAlp Dener   tao->ops->view = TaoView_BQNK;
123*e0ed867bSAlp Dener 
124*e0ed867bSAlp Dener   bnk = (TAO_BNK *)tao->data;
125*e0ed867bSAlp Dener   bnk->computehessian = TaoBQNKComputeHessian;
126*e0ed867bSAlp Dener   bnk->computestep = TaoBQNKComputeStep;
127*e0ed867bSAlp Dener   bnk->init_type = BNK_INIT_DIRECTION;
128*e0ed867bSAlp Dener 
129*e0ed867bSAlp Dener   ierr = PetscNewLog(tao,&bqnk);CHKERRQ(ierr);
130*e0ed867bSAlp Dener   bnk->ctx = (void*)bqnk;
131*e0ed867bSAlp Dener 
132*e0ed867bSAlp Dener   ierr = MatCreate(PetscObjectComm((PetscObject)tao), &bqnk->B);CHKERRQ(ierr);
133*e0ed867bSAlp Dener   ierr = PetscObjectIncrementTabLevel((PetscObject)bqnk->B, (PetscObject)tao, 1);CHKERRQ(ierr);
134*e0ed867bSAlp Dener   ierr = MatSetOptionsPrefix(bqnk->B, "tao_bqnk_");CHKERRQ(ierr);
135*e0ed867bSAlp Dener   ierr = MatSetType(bqnk->B, MATLMVMSR1);CHKERRQ(ierr);
136*e0ed867bSAlp Dener   PetscFunctionReturn(0);
137*e0ed867bSAlp Dener }