PETSC_EXTERN void PETSC_STDCALL taosetgradientroutine_(Tao *tao, void (PETSC_STDCALL *func)(Tao*, Vec *, Vec *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr) { PetscObjectAllocateFortranPointers(*tao,NFUNCS); if (!func) { *ierr = TaoSetGradientRoutine(*tao,0,ctx); } else { ((PetscObject)*tao)->fortran_func_pointers[GRAD] = (PetscVoidFunction)func; *ierr = TaoSetGradientRoutine(*tao, ourtaogradientroutine,ctx); } }
NdArray<T> minimize(NdArray<const T> x0) { GEODE_ASSERT(x0.shape==xshape); // Record boundary conditions for (auto& bc : bcs) bc.y = x0.flat[bc.x]; // Construct solution vector. const auto x = vector(); reduce(x0.flat,RawVec<T>(x->v)); // Solve using TAO const auto tao = new_<Tao>(PETSC_COMM_SELF); CHECK(TaoSetObjectiveRoutine(tao->tao,value<::Tao>,(void*)this)); CHECK(TaoSetGradientRoutine(tao->tao,gradient<::Tao>,(void*)this)); tao->set_from_options(); tao->set_initial_vector(x); tao->solve(); // Done return NdArray<T>(xshape,expand(RawVec<const T>(x->v)).flat.copy()); }
int main(int argc,char **argv) { Vec p; PetscScalar *x_ptr; PetscErrorCode ierr; PetscMPIInt size; AppCtx ctx; Vec lowerb,upperb; Tao tao; TaoConvergedReason reason; KSP ksp; PC pc; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,NULL,help); PetscFunctionBeginUser; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_SELF,1,"This is a uniprocessor example only!"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Swing equation options","");CHKERRQ(ierr); { ctx.beta = 2; ctx.c = 10000.0; ctx.u_s = 1.0; ctx.omega_s = 1.0; ctx.omega_b = 120.0*PETSC_PI; ctx.H = 5.0; ierr = PetscOptionsScalar("-Inertia","","",ctx.H,&ctx.H,NULL);CHKERRQ(ierr); ctx.D = 5.0; ierr = PetscOptionsScalar("-D","","",ctx.D,&ctx.D,NULL);CHKERRQ(ierr); ctx.E = 1.1378; ctx.V = 1.0; ctx.X = 0.545; ctx.Pmax = ctx.E*ctx.V/ctx.X;; ierr = PetscOptionsScalar("-Pmax","","",ctx.Pmax,&ctx.Pmax,NULL);CHKERRQ(ierr); ctx.Pm = 0.4; ierr = PetscOptionsScalar("-Pm","","",ctx.Pm,&ctx.Pm,NULL);CHKERRQ(ierr); ctx.tf = 0.1; ctx.tcl = 0.2; ierr = PetscOptionsReal("-tf","Time to start fault","",ctx.tf,&ctx.tf,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tcl","Time to end fault","",ctx.tcl,&ctx.tcl,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Create TAO solver and set desired solution method */ ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr); ierr = TaoSetType(tao,TAOBLMVM);CHKERRQ(ierr); /* Optimization starts */ /* Set initial solution guess */ ierr = VecCreateSeq(PETSC_COMM_WORLD,1,&p);CHKERRQ(ierr); ierr = VecGetArray(p,&x_ptr);CHKERRQ(ierr); x_ptr[0] = ctx.Pm; ierr = VecRestoreArray(p,&x_ptr);CHKERRQ(ierr); ierr = TaoSetInitialVector(tao,p);CHKERRQ(ierr); /* Set routine for function and gradient evaluation */ ierr = TaoSetObjectiveRoutine(tao,FormFunction,(void *)&ctx);CHKERRQ(ierr); ierr = TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,(void *)&ctx);CHKERRQ(ierr); /* Set bounds for the optimization */ ierr = VecDuplicate(p,&lowerb);CHKERRQ(ierr); ierr = VecDuplicate(p,&upperb);CHKERRQ(ierr); ierr = VecGetArray(lowerb,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 0.; ierr = VecRestoreArray(lowerb,&x_ptr);CHKERRQ(ierr); ierr = VecGetArray(upperb,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 1.1;; ierr = VecRestoreArray(upperb,&x_ptr);CHKERRQ(ierr); ierr = TaoSetVariableBounds(tao,lowerb,upperb); /* Check for any TAO command line options */ ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr); if (ksp) { ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); } ierr = TaoSetTolerances(tao,1e-15,1e-15,1e-15,1e-15,1e-15); /* SOLVE THE APPLICATION */ ierr = TaoSolve(tao); CHKERRQ(ierr); /* Get information on termination */ ierr = TaoGetConvergedReason(tao,&reason);CHKERRQ(ierr); if (reason <= 0){ ierr=PetscPrintf(MPI_COMM_WORLD, "Try another method! \n");CHKERRQ(ierr); } ierr = VecView(p,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Free TAO data structures */ ierr = TaoDestroy(&tao);CHKERRQ(ierr); ierr = VecDestroy(&p);CHKERRQ(ierr); ierr = VecDestroy(&lowerb);CHKERRQ(ierr); ierr = VecDestroy(&upperb);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
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); }
int main(int argc,char **argv) { Userctx user; Vec p; PetscScalar *x_ptr; PetscErrorCode ierr; PetscMPIInt size; PetscInt i; KSP ksp; PC pc; PetscInt *idx2; Tao tao; TaoConvergedReason reason; Vec lowerb,upperb; PetscFunctionBeginUser; ierr = PetscInitialize(&argc,&argv,"petscoptions",help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); ierr = VecCreateSeq(PETSC_COMM_WORLD,1,&user.vec_q);CHKERRQ(ierr); user.neqs_gen = 9*ngen; /* # eqs. for generator subsystem */ user.neqs_net = 2*nbus; /* # eqs. for network subsystem */ user.neqs_pgrid = user.neqs_gen + user.neqs_net; /* Create indices for differential and algebraic equations */ ierr = PetscMalloc1(7*ngen,&idx2);CHKERRQ(ierr); for (i=0; i<ngen; i++) { idx2[7*i] = 9*i; idx2[7*i+1] = 9*i+1; idx2[7*i+2] = 9*i+2; idx2[7*i+3] = 9*i+3; idx2[7*i+4] = 9*i+6; idx2[7*i+5] = 9*i+7; idx2[7*i+6] = 9*i+8; } ierr = ISCreateGeneral(PETSC_COMM_WORLD,7*ngen,idx2,PETSC_COPY_VALUES,&user.is_diff);CHKERRQ(ierr); ierr = ISComplement(user.is_diff,0,user.neqs_pgrid,&user.is_alg);CHKERRQ(ierr); ierr = PetscFree(idx2);CHKERRQ(ierr); /* Set run time options */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Transient stability fault options","");CHKERRQ(ierr); { user.tfaulton = 1.0; user.tfaultoff = 1.2; user.Rfault = 0.0001; user.faultbus = 8; ierr = PetscOptionsReal("-tfaulton","","",user.tfaulton,&user.tfaulton,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tfaultoff","","",user.tfaultoff,&user.tfaultoff,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-faultbus","","",user.faultbus,&user.faultbus,NULL);CHKERRQ(ierr); user.t0 = 0.0; user.tmax = 1.5; ierr = PetscOptionsReal("-t0","","",user.t0,&user.t0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tmax","","",user.tmax,&user.tmax,NULL);CHKERRQ(ierr); user.freq_u = 61.0; user.freq_l = 59.0; user.pow = 2; ierr = PetscOptionsReal("-frequ","","",user.freq_u,&user.freq_u,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-freql","","",user.freq_l,&user.freq_l,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-pow","","",user.pow,&user.pow,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Create DMs for generator and network subsystems */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,user.neqs_gen,1,1,NULL,&user.dmgen);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(user.dmgen,"dmgen_");CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,user.neqs_net,1,1,NULL,&user.dmnet);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(user.dmnet,"dmnet_");CHKERRQ(ierr); /* Create a composite DM packer and add the two DMs */ ierr = DMCompositeCreate(PETSC_COMM_WORLD,&user.dmpgrid);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(user.dmpgrid,"pgrid_");CHKERRQ(ierr); ierr = DMCompositeAddDM(user.dmpgrid,user.dmgen);CHKERRQ(ierr); ierr = DMCompositeAddDM(user.dmpgrid,user.dmnet);CHKERRQ(ierr); /* Create TAO solver and set desired solution method */ ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr); ierr = TaoSetType(tao,TAOBLMVM);CHKERRQ(ierr); /* Optimization starts */ /* Set initial solution guess */ ierr = VecCreateSeq(PETSC_COMM_WORLD,3,&p);CHKERRQ(ierr); ierr = VecGetArray(p,&x_ptr);CHKERRQ(ierr); x_ptr[0] = PG[0]; x_ptr[1] = PG[1]; x_ptr[2] = PG[2]; ierr = VecRestoreArray(p,&x_ptr);CHKERRQ(ierr); ierr = TaoSetInitialVector(tao,p);CHKERRQ(ierr); /* Set routine for function and gradient evaluation */ ierr = TaoSetObjectiveRoutine(tao,FormFunction,(void *)&user);CHKERRQ(ierr); ierr = TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,(void *)&user);CHKERRQ(ierr); /* Set bounds for the optimization */ ierr = VecDuplicate(p,&lowerb);CHKERRQ(ierr); ierr = VecDuplicate(p,&upperb);CHKERRQ(ierr); ierr = VecGetArray(lowerb,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 0.5; x_ptr[1] = 0.5; x_ptr[2] = 0.5; ierr = VecRestoreArray(lowerb,&x_ptr);CHKERRQ(ierr); ierr = VecGetArray(upperb,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 2.0; x_ptr[1] = 2.0; x_ptr[2] = 2.0; ierr = VecRestoreArray(upperb,&x_ptr);CHKERRQ(ierr); ierr = TaoSetVariableBounds(tao,lowerb,upperb); /* Check for any TAO command line options */ ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr); if (ksp) { ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); } /* SOLVE THE APPLICATION */ ierr = TaoSolve(tao); CHKERRQ(ierr); /* Get information on termination */ ierr = TaoGetConvergedReason(tao,&reason);CHKERRQ(ierr); if (reason <= 0){ ierr=PetscPrintf(MPI_COMM_WORLD, "Try another method! \n");CHKERRQ(ierr); } ierr = VecView(p,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Free TAO data structures */ ierr = TaoDestroy(&tao);CHKERRQ(ierr); ierr = VecDestroy(&user.vec_q);CHKERRQ(ierr); ierr = VecDestroy(&lowerb);CHKERRQ(ierr); ierr = VecDestroy(&upperb);CHKERRQ(ierr); ierr = VecDestroy(&p);CHKERRQ(ierr); ierr = DMDestroy(&user.dmgen);CHKERRQ(ierr); ierr = DMDestroy(&user.dmnet);CHKERRQ(ierr); ierr = DMDestroy(&user.dmpgrid);CHKERRQ(ierr); ierr = ISDestroy(&user.is_diff);CHKERRQ(ierr); ierr = ISDestroy(&user.is_alg);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }