Actual source code: almmutils.c

  1: #include <../src/tao/constrained/impls/almm/almm.h>
  2: #include <petsctao.h>
  3: #include <petsc/private/petscimpl.h>
  4: #include <petsc/private/vecimpl.h>

  6: /*@
  7:    TaoALMMGetType - Retrieve the augmented Lagrangian formulation type for the subproblem.

  9:    Input Parameters:
 10: .  tao - the `Tao` context for the `TAOALMM` solver

 12:    Output Parameters:
 13: .  type - augmented Lagragrangian type

 15:    Level: advanced

 17: .seealso: `Tao`, `TAOALMM`, `TaoALMMSetType()`, `TaoALMMType`
 18: @*/
 19: PetscErrorCode TaoALMMGetType(Tao tao, TaoALMMType *type)
 20: {
 23:   PetscUseMethod(tao, "TaoALMMGetType_C", (Tao, TaoALMMType *), (tao, type));
 24:   return 0;
 25: }

 27: PetscErrorCode TaoALMMGetType_Private(Tao tao, TaoALMMType *type)
 28: {
 29:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;

 31:   *type = auglag->type;
 32:   return 0;
 33: }

 35: /*@
 36:    TaoALMMSetType - Determine the augmented Lagrangian formulation type for the subproblem.

 38:    Input Parameters:
 39: +  tao - the Tao context for the `TAOALMM` solver
 40: -  type - augmented Lagragrangian type

 42:    Level: advanced

 44: .seealso: `Tao`, `TAOALMM`, `TaoALMMGetType()`, `TaoALMMType`
 45: @*/
 46: PetscErrorCode TaoALMMSetType(Tao tao, TaoALMMType type)
 47: {
 49:   PetscTryMethod(tao, "TaoALMMSetType_C", (Tao, TaoALMMType), (tao, type));
 50:   return 0;
 51: }

 53: PetscErrorCode TaoALMMSetType_Private(Tao tao, TaoALMMType type)
 54: {
 55:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;

 58:   auglag->type = type;
 59:   return 0;
 60: }

 62: /*@
 63:    TaoALMMGetSubsolver - Retrieve the subsolver being used by `TAOALMM`.

 65:    Input Parameters:
 66: .  tao - the `Tao` context for the `TAOALMM` solver

 68:    Output Parameter:
 69: .  subsolver - the `Tao` context for the subsolver

 71:    Level: advanced

 73: .seealso: `Tao`, `TAOALMM`, `TaoALMMSetSubsolver()`
 74: @*/
 75: PetscErrorCode TaoALMMGetSubsolver(Tao tao, Tao *subsolver)
 76: {
 79:   PetscUseMethod(tao, "TaoALMMGetSubsolver_C", (Tao, Tao *), (tao, subsolver));
 80:   return 0;
 81: }

 83: PetscErrorCode TaoALMMGetSubsolver_Private(Tao tao, Tao *subsolver)
 84: {
 85:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;

 87:   *subsolver = auglag->subsolver;
 88:   return 0;
 89: }

 91: /*@
 92:    TaoALMMSetSubsolver - Changes the subsolver inside `TAOALMM` with the user provided one.

 94:    Input Parameters:
 95: +  tao - the `Tao` context for the `TAOALMM` solver
 96: -  subsolver - the Tao context for the subsolver

 98:    Level: advanced

100:    Note:
101:    This is not recommended, instead call `TaoALMMGetSubsolver()` and set the type as desired.

103: .seealso: `Tao`, `TAOALMM`, `TaoALMMGetSubsolver()`
104: @*/
105: PetscErrorCode TaoALMMSetSubsolver(Tao tao, Tao subsolver)
106: {
109:   PetscTryMethod(tao, "TaoALMMSetSubsolver_C", (Tao, Tao), (tao, subsolver));
110:   return 0;
111: }

113: PetscErrorCode TaoALMMSetSubsolver_Private(Tao tao, Tao subsolver)
114: {
115:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;
116:   PetscBool compatible;

118:   if (subsolver == auglag->subsolver) return 0;
119:   if (tao->bounded) {
120:     PetscObjectTypeCompareAny((PetscObject)subsolver, &compatible, TAOSHELL, TAOBNCG, TAOBQNLS, TAOBQNKLS, TAOBQNKTR, TAOBQNKTL, "");
122:   } else {
123:     PetscObjectTypeCompareAny((PetscObject)subsolver, &compatible, TAOSHELL, TAOCG, TAOLMVM, TAOBNCG, TAOBQNLS, TAOBQNKLS, TAOBQNKTR, TAOBQNKTL, "");
125:   }
127:   PetscObjectReference((PetscObject)subsolver);
128:   TaoDestroy(&auglag->subsolver);
129:   auglag->subsolver = subsolver;
130:   if (tao->setupcalled) {
131:     TaoSetSolution(auglag->subsolver, auglag->P);
132:     TaoSetObjective(auglag->subsolver, TaoALMMSubsolverObjective_Private, (void *)auglag);
133:     TaoSetObjectiveAndGradient(auglag->subsolver, NULL, TaoALMMSubsolverObjectiveAndGradient_Private, (void *)auglag);
134:     TaoSetVariableBounds(auglag->subsolver, auglag->PL, auglag->PU);
135:   }
136:   return 0;
137: }

139: /*@
140:    TaoALMMGetMultipliers - Retrieve a pointer to the Lagrange multipliers.

142:    Input Parameters:
143: .  tao - the `Tao` context for the `TAOALMM` solver

145:    Output Parameters:
146: .  Y - vector of Lagrange multipliers

148:    Level: advanced

150:    Notes:
151:    For problems with both equality and inequality constraints,
152:    the multipliers are combined together as Y = (Ye, Yi). Users
153:    can recover copies of the subcomponents using index sets
154:    provided by `TaoALMMGetDualIS()` and use `VecGetSubVector()`.

156: .seealso: `TAOALMM`, `Tao`, `TaoALMMSetMultipliers()`, `TaoALMMGetDualIS()`
157: @*/
158: PetscErrorCode TaoALMMGetMultipliers(Tao tao, Vec *Y)
159: {
162:   PetscUseMethod(tao, "TaoALMMGetMultipliers_C", (Tao, Vec *), (tao, Y));
163:   return 0;
164: }

166: PetscErrorCode TaoALMMGetMultipliers_Private(Tao tao, Vec *Y)
167: {
168:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;

171:   *Y = auglag->Y;
172:   return 0;
173: }

175: /*@
176:    TaoALMMSetMultipliers - Set user-defined Lagrange multipliers. The vector type and
177:                              parallel structure of the given vectormust match equality and
178:                              inequality constraints. The vector must have a local size equal
179:                              to the sum of the local sizes for the constraint vectors, and a
180:                              global size equal to the sum of the global sizes of the constraint
181:                              vectors.

183:    Input Parameters:
184: +  tao - the `Tao` context for the `TAOALMM` solver
185: -  Y - vector of Lagrange multipliers

187:    Level: advanced

189:    Notes:
190:    This routine is only useful if the user wants to change the
191:    parallel distribution of the combined dual vector in problems that
192:    feature both equality and inequality constraints. For other tasks,
193:    it is strongly recommended that the user retrieve the dual vector
194:    created by the solver using TaoALMMGetMultipliers().

196: .seealso: `TAOALMM`, `Tao`, `TaoALMMGetMultipliers()`
197: @*/
198: PetscErrorCode TaoALMMSetMultipliers(Tao tao, Vec Y)
199: {
202:   PetscTryMethod(tao, "TaoALMMSetMultipliers_C", (Tao, Vec), (tao, Y));
203:   return 0;
204: }

206: PetscErrorCode TaoALMMSetMultipliers_Private(Tao tao, Vec Y)
207: {
208:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;
209:   VecType   Ytype;
210:   PetscInt  Nuser, Neq, Nineq, N;
211:   PetscBool same = PETSC_FALSE;

213:   /* no-op if user provides vector from TaoALMMGetMultipliers() */
214:   if (Y == auglag->Y) return 0;
215:   /* make sure vector type is same as equality and inequality constraints */
216:   if (tao->eq_constrained) {
217:     VecGetType(tao->constraints_equality, &Ytype);
218:   } else {
219:     VecGetType(tao->constraints_inequality, &Ytype);
220:   }
221:   PetscObjectTypeCompare((PetscObject)Y, Ytype, &same);
223:   /* make sure global size matches sum of equality and inequality */
224:   if (tao->eq_constrained) {
225:     VecGetSize(tao->constraints_equality, &Neq);
226:   } else {
227:     Neq = 0;
228:   }
229:   if (tao->ineq_constrained) {
230:     VecGetSize(tao->constraints_inequality, &Nineq);
231:   } else {
232:     Nineq = 0;
233:   }
234:   N = Neq + Nineq;
235:   VecGetSize(Y, &Nuser);
237:   /* if there is only one type of constraint, then we need the local size to match too */
238:   if (Neq == 0) {
239:     VecGetLocalSize(tao->constraints_inequality, &Nineq);
240:     VecGetLocalSize(Y, &Nuser);
242:   }
243:   if (Nineq == 0) {
244:     VecGetLocalSize(tao->constraints_equality, &Neq);
245:     VecGetLocalSize(Y, &Nuser);
247:   }
248:   /* if we got here, the given vector is compatible so we can replace the current one */
249:   PetscObjectReference((PetscObject)Y);
250:   VecDestroy(&auglag->Y);
251:   auglag->Y = Y;
252:   /* if there are both types of constraints and the solver has already been set up,
253:      then we need to regenerate VecScatter objects for the new combined dual vector */
254:   if (tao->setupcalled && tao->eq_constrained && tao->ineq_constrained) {
255:     VecDestroy(&auglag->C);
256:     VecDuplicate(auglag->Y, &auglag->C);
257:     VecScatterDestroy(&auglag->Yscatter[0]);
258:     VecScatterCreate(auglag->Y, auglag->Yis[0], auglag->Ye, NULL, &auglag->Yscatter[0]);
259:     VecScatterDestroy(&auglag->Yscatter[1]);
260:     VecScatterCreate(auglag->Y, auglag->Yis[1], auglag->Yi, NULL, &auglag->Yscatter[1]);
261:   }
262:   return 0;
263: }

265: /*@
266:    TaoALMMGetPrimalIS - Retrieve a pointer to the index set that identifies optimization
267:                         and slack variable components of the subsolver's solution vector.
268:                         Not valid for problems with only equality constraints.

270:    Input Parameter:
271: .  tao - the `Tao` context for the `TAOALMM` solver

273:    Output Parameters:
274: +  opt_is - index set associated with the optimization variables (NULL if not needed)
275: -  slack_is - index set associated with the slack variables (NULL if not needed)

277:    Level: advanced

279: .seealso: `TAOALMM`, `Tao`, `IS`, `TaoALMMGetPrimalVector()`
280: @*/
281: PetscErrorCode TaoALMMGetPrimalIS(Tao tao, IS *opt_is, IS *slack_is)
282: {
284:   PetscUseMethod(tao, "TaoALMMGetPrimalIS_C", (Tao, IS *, IS *), (tao, opt_is, slack_is));
285:   return 0;
286: }

288: PetscErrorCode TaoALMMGetPrimalIS_Private(Tao tao, IS *opt_is, IS *slack_is)
289: {
290:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;

294:   if (opt_is) *opt_is = auglag->Pis[0];
295:   if (slack_is) *slack_is = auglag->Pis[1];
296:   return 0;
297: }

299: /*@
300:    TaoALMMGetDualIS - Retrieve a pointer to the index set that identifies equality
301:                       and inequality constraint components of the dual vector returned
302:                       by `TaoALMMGetMultipliers()`. Not valid for problems with only one
303:                       type of constraint.

305:    Input Parameter:
306: .  tao - the Tao context for the `TAOALMM` solver

308:    Output Parameters:
309: +  eq_is - index set associated with the equality constraints (NULL if not needed)
310: -  ineq_is - index set associated with the inequality constraints (NULL if not needed)

312:    Level: advanced

314: .seealso: `TAOALMM`, `Tao`, `TaoALMMGetMultipliers()`
315: @*/
316: PetscErrorCode TaoALMMGetDualIS(Tao tao, IS *eq_is, IS *ineq_is)
317: {
319:   PetscUseMethod(tao, "TaoALMMGetDualIS_C", (Tao, IS *, IS *), (tao, eq_is, ineq_is));
320:   return 0;
321: }

323: PetscErrorCode TaoALMMGetDualIS_Private(Tao tao, IS *eq_is, IS *ineq_is)
324: {
325:   TAO_ALMM *auglag = (TAO_ALMM *)tao->data;

330:   if (eq_is) *eq_is = auglag->Yis[0];
331:   if (ineq_is) *ineq_is = auglag->Yis[1];
332:   return 0;
333: }