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