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: }