MittelmannBndryCntrlDiri3D.hpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. // Copyright (C) 2005, 2007 International Business Machines and others.
  2. // All Rights Reserved.
  3. // This code is published under the Eclipse Public License.
  4. //
  5. // $Id: MittelmannBndryCntrlDiri3D.hpp 2005 2011-06-06 12:55:16Z stefan $
  6. //
  7. // Authors: Andreas Waechter IBM 2005-10-18
  8. // Olaf Schenk (Univ. of Basel) 2007-08-01
  9. // modified MittelmannBndryCntrlDiri.hpp for 3-dim problem
  10. #ifndef __MITTELMANNBNDRYCNTRLDIRI3D_HPP__
  11. #define __MITTELMANNBNDRYCNTRLDIRI3D_HPP__
  12. #include "RegisteredTNLP.hpp"
  13. #ifdef HAVE_CONFIG_H
  14. #include "config.h"
  15. #else
  16. #include "configall_system.h"
  17. #endif
  18. #ifdef HAVE_CMATH
  19. # include <cmath>
  20. #else
  21. # ifdef HAVE_MATH_H
  22. # include <math.h>
  23. # else
  24. # error "don't have header file for math"
  25. # endif
  26. #endif
  27. #ifdef HAVE_CSTDIO
  28. # include <cstdio>
  29. #else
  30. # ifdef HAVE_STDIO_H
  31. # include <stdio.h>
  32. # else
  33. # error "don't have header file for stdio"
  34. # endif
  35. #endif
  36. using namespace Ipopt;
  37. /** Base class for boundary control problems with Dirichlet boundary
  38. * conditions, as formulated by Hans Mittelmann as Examples 1-4 in
  39. * "Optimization Techniques for Solving Elliptic Control Problems
  40. * with Control and State Constraints. Part 2: Boundary Control"
  41. *
  42. * Here, the control variables are identical to the values of y on
  43. * the boundary, and therefore we don't need any explicit
  44. * optimization variables for u.
  45. */
  46. class MittelmannBndryCntrlDiriBase3D : public RegisteredTNLP
  47. {
  48. public:
  49. /** Constructor. */
  50. MittelmannBndryCntrlDiriBase3D();
  51. /** Default destructor */
  52. virtual ~MittelmannBndryCntrlDiriBase3D();
  53. /**@name Overloaded from TNLP */
  54. //@{
  55. /** Method to return some info about the nlp */
  56. virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
  57. Index& nnz_h_lag, IndexStyleEnum& index_style);
  58. /** Method to return the bounds for my problem */
  59. virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
  60. Index m, Number* g_l, Number* g_u);
  61. /** Method to return the starting point for the algorithm */
  62. virtual bool get_starting_point(Index n, bool init_x, Number* x,
  63. bool init_z, Number* z_L, Number* z_U,
  64. Index m, bool init_lambda,
  65. Number* lambda);
  66. /** Method to return the objective value */
  67. virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value);
  68. /** Method to return the gradient of the objective */
  69. virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f);
  70. /** Method to return the constraint residuals */
  71. virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g);
  72. /** Method to return:
  73. * 1) The structure of the jacobian (if "values" is NULL)
  74. * 2) The values of the jacobian (if "values" is not NULL)
  75. */
  76. virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
  77. Index m, Index nele_jac, Index* iRow, Index *jCol,
  78. Number* values);
  79. /** Method to return:
  80. * 1) The structure of the hessian of the lagrangian (if "values" is NULL)
  81. * 2) The values of the hessian of the lagrangian (if "values" is not NULL)
  82. */
  83. virtual bool eval_h(Index n, const Number* x, bool new_x,
  84. Number obj_factor, Index m, const Number* lambda,
  85. bool new_lambda, Index nele_hess, Index* iRow,
  86. Index* jCol, Number* values);
  87. //@}
  88. /** Method for returning scaling parameters */
  89. virtual bool get_scaling_parameters(Number& obj_scaling,
  90. bool& use_x_scaling, Index n,
  91. Number* x_scaling,
  92. bool& use_g_scaling, Index m,
  93. Number* g_scaling);
  94. /** @name Solution Methods */
  95. //@{
  96. /** This method is called after the optimization, and could write an
  97. * output file with the optimal profiles */
  98. virtual void finalize_solution(SolverReturn status,
  99. Index n, const Number* x, const Number* z_L, const Number* z_U,
  100. Index m, const Number* g, const Number* lambda,
  101. Number obj_valu,
  102. const IpoptData* ip_data,
  103. IpoptCalculatedQuantities* ip_cq);
  104. //@}
  105. protected:
  106. /** Method for setting the internal parameters that define the
  107. * problem. It must be called by the child class in its
  108. * implementation of InitializeParameters. */
  109. void SetBaseParameters(Index N, Number alpha, Number lb_y,
  110. Number ub_y, Number lb_u, Number ub_u,
  111. Number d_const, Number B, Number C);
  112. /**@name Functions that defines a particular instance. */
  113. //@{
  114. /** Target profile function for y */
  115. virtual Number y_d_cont(Number x1, Number x2, Number x3) const =0;
  116. //@}
  117. private:
  118. /**@name Methods to block default compiler methods.
  119. * The compiler automatically generates the following three methods.
  120. * Since the default compiler implementation is generally not what
  121. * you want (for all but the most simple classes), we usually
  122. * put the declarations of these methods in the private section
  123. * and never implement them. This prevents the compiler from
  124. * implementing an incorrect "default" behavior without us
  125. * knowing. (See Scott Meyers book, "Effective C++")
  126. *
  127. */
  128. //@{
  129. MittelmannBndryCntrlDiriBase3D(const MittelmannBndryCntrlDiriBase3D&);
  130. MittelmannBndryCntrlDiriBase3D& operator=(const MittelmannBndryCntrlDiriBase3D&);
  131. //@}
  132. /**@name Problem specification */
  133. //@{
  134. /** Number of mesh points in one dimension (excluding boundary) */
  135. Index N_;
  136. /** Step size */
  137. Number h_;
  138. /** h_ squared */
  139. Number hh_;
  140. /** h_ to the third power */
  141. Number hhh_;
  142. /** overall lower bound on y */
  143. Number lb_y_;
  144. /** overall upper bound on y */
  145. Number ub_y_;
  146. /** overall lower bound on u */
  147. Number lb_u_;
  148. /** overall upper bound on u */
  149. Number ub_u_;
  150. /** Constant value of d appearing in elliptical equation */
  151. Number d_const_;
  152. /** Weighting parameter for the control target deviation functional
  153. * in the objective */
  154. Number alpha_;
  155. /** Array for the target profile for y */
  156. Number* y_d_;
  157. //@}
  158. /**@name Auxilliary methods */
  159. //@{
  160. /** Translation of mesh point indices to NLP variable indices for
  161. * y(x_ijk) */
  162. inline Index y_index(Index i, Index j, Index k) const
  163. {
  164. return k + (N_+2)*j + (N_+2)*(N_+2)*i;
  165. }
  166. /** Translation of interior mesh point indices to the corresponding
  167. * PDE constraint number */
  168. inline Index pde_index(Index i, Index j, Index k) const
  169. {
  170. return (k-1) + N_*(j-1) + N_*N_*(i-1);
  171. }
  172. /** Compute the grid coordinate for given index in x1 direction */
  173. inline Number x1_grid(Index i) const
  174. {
  175. return h_*(Number)i;
  176. }
  177. /** Compute the grid coordinate for given index in x2 direction */
  178. inline Number x2_grid(Index i) const
  179. {
  180. return h_*(Number)i;
  181. }
  182. /** Compute the grid coordinate for given index in x3 direction */
  183. inline Number x3_grid(Index i) const
  184. {
  185. return h_*(Number)i;
  186. }
  187. /** value of penalty function term */
  188. inline Number PenObj(Number t) const
  189. {
  190. //return 0.5*t*t;
  191. if (t > B_) {
  192. return B_*B_/2. + C_*(t - B_);
  193. }
  194. else if (t < -B_) {
  195. return B_*B_/2. + C_*(-t - B_);
  196. }
  197. else {
  198. const Number t2 = t*t;
  199. const Number t4 = t2*t2;
  200. const Number t6 = t4*t2;
  201. return PenA_*t2 + PenB_*t4 + PenC_*t6;
  202. }
  203. }
  204. /** first derivative of penalty function term */
  205. inline Number PenObj_1(Number t) const
  206. {
  207. //return t;
  208. if (t > B_) {
  209. return C_;
  210. }
  211. else if (t < -B_) {
  212. return -C_;
  213. }
  214. else {
  215. const Number t2 = t*t;
  216. const Number t3 = t*t2;
  217. const Number t5 = t3*t2;
  218. return 2.*PenA_*t + 4.*PenB_*t3 + 6.*PenC_*t5;
  219. }
  220. }
  221. /** second derivative of penalty function term */
  222. inline Number PenObj_2(Number t) const
  223. {
  224. //return 1.;
  225. if (t > B_) {
  226. return 0.;
  227. }
  228. else if (t < -B_) {
  229. return 0.;
  230. }
  231. else {
  232. const Number t2 = t*t;
  233. const Number t4 = t2*t2;
  234. return 2.*PenA_ + 12.*PenB_*t2 + 30.*PenC_*t4;
  235. }
  236. }
  237. //@}
  238. /** @name Data for penalty function term */
  239. //@{
  240. Number B_;
  241. Number C_;
  242. Number PenA_;
  243. Number PenB_;
  244. Number PenC_;
  245. //@}
  246. };
  247. /** Class implementating Example 1 */
  248. class MittelmannBndryCntrlDiri3D : public MittelmannBndryCntrlDiriBase3D
  249. {
  250. public:
  251. MittelmannBndryCntrlDiri3D()
  252. {}
  253. virtual ~MittelmannBndryCntrlDiri3D()
  254. {}
  255. virtual bool InitializeProblem(Index N)
  256. {
  257. if (N<1) {
  258. printf("N has to be at least 1.");
  259. return false;
  260. }
  261. Number alpha = 0.01;
  262. Number lb_y = -1e20;
  263. Number ub_y = 3.5;
  264. Number lb_u = 0.;
  265. Number ub_u = 10.;
  266. Number d_const = -20.;
  267. Number B = .5;
  268. Number C = 0.01;
  269. SetBaseParameters(N, alpha, lb_y, ub_y, lb_u, ub_u, d_const, B, C);
  270. return true;
  271. }
  272. protected:
  273. /** Target profile function for y */
  274. virtual Number y_d_cont(Number x1, Number x2, Number x3) const
  275. {
  276. return 3. + 5.*(x1*(x1-1.)*x2*(x2-1.));
  277. }
  278. private:
  279. /**@name hide implicitly defined contructors copy operators */
  280. //@{
  281. MittelmannBndryCntrlDiri3D(const MittelmannBndryCntrlDiri3D&);
  282. MittelmannBndryCntrlDiri3D& operator=(const MittelmannBndryCntrlDiri3D&);
  283. //@}
  284. };
  285. #endif