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