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: 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: 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 a pointer to the 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: 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: .seealso: TAOALMM, TaoALMMGetSubsolver()
101: @*/
102: PetscErrorCode TaoALMMSetSubsolver(Tao tao, Tao subsolver)
103: {
106:    PetscTryMethod(tao,"TaoALMMSetSubsolver_C",(Tao,Tao),(tao,subsolver));
107:    return 0;
108: }

110: PetscErrorCode TaoALMMSetSubsolver_Private(Tao tao, Tao subsolver)
111: {
112:   TAO_ALMM       *auglag = (TAO_ALMM*)tao->data;
113:   PetscBool      compatible;

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

136: /*@
137:    TaoALMMGetMultipliers - Retrieve a pointer to the Lagrange multipliers.

139:    Input Parameters:
140: .  tao - the Tao context for the TAOALMM solver

142:    Output Parameters:
143: .  Y - vector of Lagrange multipliers

145:    Level: advanced

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

153: .seealso: TAOALMM, TaoALMMSetMultipliers(), TaoALMMGetDualIS()
154: @*/
155: PetscErrorCode TaoALMMGetMultipliers(Tao tao, Vec *Y)
156: {
159:   PetscUseMethod(tao,"TaoALMMGetMultipliers_C",(Tao,Vec *),(tao,Y));
160:   return 0;
161: }

163: PetscErrorCode TaoALMMGetMultipliers_Private(Tao tao, Vec *Y)
164: {
165:   TAO_ALMM *auglag = (TAO_ALMM*)tao->data;

168:   *Y = auglag->Y;
169:   return 0;
170: }

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

180:    Input Parameters:
181: +  tao - the Tao context for the TAOALMM solver
182: -  Y - vector of Lagrange multipliers

184:    Level: advanced

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

193: .seealso: TAOALMM, TaoALMMGetMultipliers()
194: @*/
195: PetscErrorCode TaoALMMSetMultipliers(Tao tao, Vec Y)
196: {
199:   PetscTryMethod(tao,"TaoALMMSetMultipliers_C",(Tao,Vec),(tao,Y));
200:   return 0;
201: }

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

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

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

267:    Input Parameter:
268: .  tao - the Tao context for the TAOALMM solver

270:    Output Parameters:
271: +  opt_is - index set associated with the optimization variables (NULL if not needed)
272: -  slack_is - index set associated with the slack variables (NULL if not needed)

274:    Level: advanced

276: .seealso: TAOALMM, TaoALMMGetPrimalVector()
277: @*/
278: PetscErrorCode TaoALMMGetPrimalIS(Tao tao, IS *opt_is, IS *slack_is)
279: {
281:   PetscUseMethod(tao,"TaoALMMGetPrimalIS_C",(Tao,IS *,IS *),(tao,opt_is,slack_is));
282:   return 0;
283: }

285: PetscErrorCode TaoALMMGetPrimalIS_Private(Tao tao, IS *opt_is, IS *slack_is)
286: {
287:   TAO_ALMM *auglag = (TAO_ALMM*)tao->data;

291:   if (opt_is) *opt_is = auglag->Pis[0];
292:   if (slack_is) *slack_is = auglag->Pis[1];
293:   return 0;
294: }

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

302:    Input Parameter:
303: .  tao - the Tao context for the TAOALMM solver

305:    Output Parameters:
306: +  eq_is - index set associated with the equality constraints (NULL if not needed)
307: -  ineq_is - index set associated with the inequality constraints (NULL if not needed)

309:    Level: advanced

311: .seealso: TAOALMM, TaoALMMGetMultipliers()
312: @*/
313: PetscErrorCode TaoALMMGetDualIS(Tao tao, IS *eq_is, IS *ineq_is)
314: {
316:    PetscUseMethod(tao,"TaoALMMGetDualIS_C",(Tao,IS *,IS *),(tao,eq_is,ineq_is));
317:    return 0;
318: }

320: PetscErrorCode TaoALMMGetDualIS_Private(Tao tao, IS *eq_is, IS *ineq_is)
321: {
322:   TAO_ALMM *auglag = (TAO_ALMM*)tao->data;

327:   if (eq_is) *eq_is = auglag->Yis[0];
328:   if (ineq_is) *ineq_is = auglag->Yis[1];
329:   return 0;
330: }