void TaoOptimizationSolver<T>::solve ()
{
  LOG_SCOPE("solve()", "TaoOptimizationSolver");

  this->init ();

  this->system().solution->zero();

  PetscMatrix<T> * hessian  = cast_ptr<PetscMatrix<T> *>(this->system().matrix);
  // PetscVector<T> * gradient = cast_ptr<PetscVector<T> *>(this->system().rhs);
  PetscVector<T> * x         = cast_ptr<PetscVector<T> *>(this->system().solution.get());
  PetscVector<T> * ceq       = cast_ptr<PetscVector<T> *>(this->system().C_eq.get());
  PetscMatrix<T> * ceq_jac   = cast_ptr<PetscMatrix<T> *>(this->system().C_eq_jac.get());
  PetscVector<T> * cineq     = cast_ptr<PetscVector<T> *>(this->system().C_ineq.get());
  PetscMatrix<T> * cineq_jac = cast_ptr<PetscMatrix<T> *>(this->system().C_ineq_jac.get());
  PetscVector<T> * lb        = cast_ptr<PetscVector<T> *>(&this->system().get_vector("lower_bounds"));
  PetscVector<T> * ub        = cast_ptr<PetscVector<T> *>(&this->system().get_vector("upper_bounds"));

  // Set the starting guess to zero.
  x->zero();

  PetscErrorCode ierr = 0;

  // Workaround for bug where TaoSetFromOptions *reset*
  // programmatically set tolerance and max. function evaluation
  // values when "-tao_type ipm" was specified on the command line: we
  // call TaoSetFromOptions twice (both before and after setting
  // custom options programatically)
  ierr = TaoSetFromOptions(_tao);
  LIBMESH_CHKERR(ierr);

  // Set convergence tolerances
  // f(X) - f(X*) (estimated)            <= fatol
  // |f(X) - f(X*)| (estimated) / |f(X)| <= frtol
  // ||g(X)||                            <= gatol
  // ||g(X)|| / |f(X)|                   <= grtol
  // ||g(X)|| / ||g(X0)||                <= gttol
  // Command line equivalents: -tao_fatol, -tao_frtol, -tao_gatol, -tao_grtol, -tao_gttol
  ierr = TaoSetTolerances(_tao,
#if PETSC_RELEASE_LESS_THAN(3,7,0)
                          // Releases up to 3.X.Y had fatol and frtol, after that they were removed.
                          // Hopefully we'll be able to know X and Y soon. Guessing at 3.7.0.
                          /*fatol=*/PETSC_DEFAULT,
                          /*frtol=*/PETSC_DEFAULT,
#endif
                          /*gatol=*/PETSC_DEFAULT,
                          /*grtol=*/this->objective_function_relative_tolerance,
                          /*gttol=*/PETSC_DEFAULT);
  LIBMESH_CHKERR(ierr);

  // Set the max-allowed number of objective function evaluations
  // Command line equivalent: -tao_max_funcs
  ierr = TaoSetMaximumFunctionEvaluations(_tao, this->max_objective_function_evaluations);
  LIBMESH_CHKERR(ierr);

  // Set the max-allowed number of optimization iterations.
  // Command line equivalent: -tao_max_it
  // Not implemented for now as it seems fairly similar to
  // ierr = TaoSetMaximumIterations(_tao, 4);
  // LIBMESH_CHKERR(ierr);

  // Set solution vec and an initial guess
  ierr = TaoSetInitialVector(_tao, x->vec());
  LIBMESH_CHKERR(ierr);

  // We have to have an objective function
  libmesh_assert( this->objective_object );

  // Set routines for objective, gradient, hessian evaluation
  ierr = TaoSetObjectiveRoutine(_tao, __libmesh_tao_objective, this);
  LIBMESH_CHKERR(ierr);

  if ( this->gradient_object )
    {
      ierr = TaoSetGradientRoutine(_tao, __libmesh_tao_gradient, this);
      LIBMESH_CHKERR(ierr);
    }

  if ( this->hessian_object )
    {
      ierr = TaoSetHessianRoutine(_tao, hessian->mat(), hessian->mat(), __libmesh_tao_hessian, this);
      LIBMESH_CHKERR(ierr);
    }

  if ( this->lower_and_upper_bounds_object )
    {
      // Need to actually compute the bounds vectors first
      this->lower_and_upper_bounds_object->lower_and_upper_bounds(this->system());

      ierr = TaoSetVariableBounds(_tao,
                                  lb->vec(),
                                  ub->vec());
      LIBMESH_CHKERR(ierr);
    }

  if ( this->equality_constraints_object )
    {
      ierr = TaoSetEqualityConstraintsRoutine(_tao, ceq->vec(), __libmesh_tao_equality_constraints, this);
      LIBMESH_CHKERR(ierr);
    }

  if ( this->equality_constraints_jacobian_object )
    {
      ierr = TaoSetJacobianEqualityRoutine(_tao,
                                           ceq_jac->mat(),
                                           ceq_jac->mat(),
                                           __libmesh_tao_equality_constraints_jacobian,
                                           this);
      LIBMESH_CHKERR(ierr);
    }

  // Optionally set inequality constraints
  if ( this->inequality_constraints_object )
    {
      ierr = TaoSetInequalityConstraintsRoutine(_tao, cineq->vec(), __libmesh_tao_inequality_constraints, this);
      LIBMESH_CHKERR(ierr);
    }

  // Optionally set inequality constraints Jacobian
  if ( this->inequality_constraints_jacobian_object )
    {
      ierr = TaoSetJacobianInequalityRoutine(_tao,
                                             cineq_jac->mat(),
                                             cineq_jac->mat(),
                                             __libmesh_tao_inequality_constraints_jacobian,
                                             this);
      LIBMESH_CHKERR(ierr);
    }

  // Check for Tao command line options
  ierr = TaoSetFromOptions(_tao);
  LIBMESH_CHKERR(ierr);

  // Perform the optimization
  ierr = TaoSolve(_tao);
  LIBMESH_CHKERR(ierr);

  // Store the convergence/divergence reason
  ierr = TaoGetConvergedReason(_tao, &_reason);
  LIBMESH_CHKERR(ierr);
}
示例#2
0
文件: maros.c 项目: tom-klotz/petsc
PetscErrorCode main(int argc,char **argv)
{
  PetscErrorCode     ierr;                /* used to check for functions returning nonzeros */
  PetscMPIInt        size;
  Vec                x;                   /* solution */
  KSP                ksp;
  PC                 pc;
  Vec                ceq,cin;
  PetscBool          flg;                 /* A return value when checking for use options */
  Tao                tao;                 /* Tao solver context */
  TaoConvergedReason reason;
  AppCtx             user;                /* application context */

  /* Initialize TAO,PETSc */
  ierr = PetscInitialize(&argc,&argv,(char *)0,help);CHKERRQ(ierr);
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
  /* Specify default parameters for the problem, check for command-line overrides */
  ierr = PetscStrncpy(user.name,"HS21",8);CHKERRQ(ierr);
  ierr = PetscOptionsGetString(NULL,NULL,"-cutername",user.name,24,&flg);CHKERRQ(ierr);

  ierr = PetscPrintf(PETSC_COMM_WORLD,"\n---- MAROS Problem %s -----\n",user.name);CHKERRQ(ierr);
  ierr = InitializeProblem(&user);CHKERRQ(ierr);
  ierr = VecDuplicate(user.d,&x);CHKERRQ(ierr);
  ierr = VecDuplicate(user.beq,&ceq);CHKERRQ(ierr);
  ierr = VecDuplicate(user.bin,&cin);CHKERRQ(ierr);
  ierr = VecSet(x,1.0);CHKERRQ(ierr);

  ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr);
  ierr = TaoSetType(tao,TAOIPM);CHKERRQ(ierr);
  ierr = TaoSetInitialVector(tao,x);CHKERRQ(ierr);
  ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetEqualityConstraintsRoutine(tao,ceq,FormEqualityConstraints,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetInequalityConstraintsRoutine(tao,cin,FormInequalityConstraints,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetInequalityBounds(tao,user.bin,NULL);CHKERRQ(ierr);
  ierr = TaoSetJacobianEqualityRoutine(tao,user.Aeq,user.Aeq,FormEqualityJacobian,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetJacobianInequalityRoutine(tao,user.Ain,user.Ain,FormInequalityJacobian,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetHessianRoutine(tao,user.H,user.H,FormHessian,(void*)&user);CHKERRQ(ierr);
  ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr);
  ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
  ierr = PCSetType(pc,PCLU);CHKERRQ(ierr);
  /*
      This algorithm produces matrices with zeros along the diagonal therefore we need to use
    SuperLU which does partial pivoting
  */
  ierr = PCFactorSetMatSolverPackage(pc,MATSOLVERSUPERLU);CHKERRQ(ierr);
  ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr);
  ierr = TaoSetTolerances(tao,0,0,0);CHKERRQ(ierr);

  ierr = TaoSetFromOptions(tao);CHKERRQ(ierr);
  ierr = TaoSolve(tao);CHKERRQ(ierr);
  ierr = TaoGetConvergedReason(tao,&reason);CHKERRQ(ierr);
  if (reason < 0) {
    ierr = PetscPrintf(MPI_COMM_WORLD, "TAO failed to converge due to %s.\n",TaoConvergedReasons[reason]);CHKERRQ(ierr);
  } else {
    ierr = PetscPrintf(MPI_COMM_WORLD, "Optimization completed with status %s.\n",TaoConvergedReasons[reason]);CHKERRQ(ierr);
  }

  ierr = DestroyProblem(&user);CHKERRQ(ierr);
  ierr = VecDestroy(&x);CHKERRQ(ierr);
  ierr = VecDestroy(&ceq);CHKERRQ(ierr);
  ierr = VecDestroy(&cin);CHKERRQ(ierr);
  ierr = TaoDestroy(&tao);CHKERRQ(ierr);

  ierr = PetscFinalize();
  return ierr;
}
示例#3
0
文件: toy.c 项目: tom-klotz/petsc
PetscErrorCode main(int argc,char **argv)
{
    PetscErrorCode     ierr;                /* used to check for functions returning nonzeros */
    Tao                tao;
    KSP                ksp;
    PC                 pc;
    AppCtx             user;                /* application context */

    ierr = PetscInitialize(&argc,&argv,(char *)0,help);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"\n---- TOY Problem -----\n");
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Solution should be f(1,1)=-2\n");
    CHKERRQ(ierr);
    ierr = InitializeProblem(&user);
    CHKERRQ(ierr);
    ierr = TaoCreate(PETSC_COMM_WORLD,&tao);
    CHKERRQ(ierr);
    ierr = TaoSetType(tao,TAOIPM);
    CHKERRQ(ierr);
    ierr = TaoSetInitialVector(tao,user.x);
    CHKERRQ(ierr);
    ierr = TaoSetVariableBounds(tao,user.xl,user.xu);
    CHKERRQ(ierr);
    ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void*)&user);
    CHKERRQ(ierr);

    ierr = TaoSetEqualityConstraintsRoutine(tao,user.ce,FormEqualityConstraints,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetInequalityConstraintsRoutine(tao,user.ci,FormInequalityConstraints,(void*)&user);
    CHKERRQ(ierr);

    ierr = TaoSetJacobianEqualityRoutine(tao,user.Ae,user.Ae,FormEqualityJacobian,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetJacobianInequalityRoutine(tao,user.Ai,user.Ai,FormInequalityJacobian,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetHessianRoutine(tao,user.H,user.H,FormHessian,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetTolerances(tao,0,0,0);
    CHKERRQ(ierr);

    ierr = TaoSetFromOptions(tao);
    CHKERRQ(ierr);

    ierr = TaoGetKSP(tao,&ksp);
    CHKERRQ(ierr);
    ierr = KSPGetPC(ksp,&pc);
    CHKERRQ(ierr);
    ierr = PCSetType(pc,PCLU);
    CHKERRQ(ierr);
    /*
        This algorithm produces matrices with zeros along the diagonal therefore we need to use
      SuperLU which does partial pivoting
    */
    ierr = PCFactorSetMatSolverPackage(pc,MATSOLVERSUPERLU);
    CHKERRQ(ierr);
    ierr = KSPSetType(ksp,KSPPREONLY);
    CHKERRQ(ierr);
    ierr = KSPSetFromOptions(ksp);
    CHKERRQ(ierr);

    ierr = TaoSetTolerances(tao,0,0,0);
    CHKERRQ(ierr);
    ierr = TaoSolve(tao);
    CHKERRQ(ierr);

    ierr = DestroyProblem(&user);
    CHKERRQ(ierr);
    ierr = TaoDestroy(&tao);
    CHKERRQ(ierr);
    ierr = PetscFinalize();
    return ierr;
}