MittelmannBndryCntrlDiri3D_27.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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_27.hpp 2005 2011-06-06 12:55:16Z stefan $
  6. //
  7. // Authors: Olaf Schenk (Univ. of Basel) 2007-08-01
  8. // modified MittelmannBndryCntrlDiri.hpp for 3-dim problem
  9. // based on MyNLP.hpp
  10. #ifndef __MITTELMANNBNDRYCNTRLDIRI3D_27_HPP__
  11. #define __MITTELMANNBNDRYCNTRLDIRI3D_27_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_27 : public RegisteredTNLP
  47. {
  48. public:
  49. /** Constructor. */
  50. MittelmannBndryCntrlDiriBase3D_27();
  51. /** Default destructor */
  52. virtual ~MittelmannBndryCntrlDiriBase3D_27();
  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_27(const MittelmannBndryCntrlDiriBase3D_27&);
  130. MittelmannBndryCntrlDiriBase3D_27& operator=(const MittelmannBndryCntrlDiriBase3D_27&);
  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. if (B_ == 0.) {
  191. return 0.5*t*t;
  192. }
  193. else if (t > B_) {
  194. return B_*B_/2. + C_*(t - B_);
  195. }
  196. else if (t < -B_) {
  197. return B_*B_/2. + C_*(-t - B_);
  198. }
  199. else {
  200. const Number t2 = t*t;
  201. const Number t4 = t2*t2;
  202. const Number t6 = t4*t2;
  203. return PenA_*t2 + PenB_*t4 + PenC_*t6;
  204. }
  205. }
  206. /** first derivative of penalty function term */
  207. inline Number PenObj_1(Number t) const
  208. {
  209. if (B_ == 0.) {
  210. return t;
  211. }
  212. else if (t > B_) {
  213. return C_;
  214. }
  215. else if (t < -B_) {
  216. return -C_;
  217. }
  218. else {
  219. const Number t2 = t*t;
  220. const Number t3 = t*t2;
  221. const Number t5 = t3*t2;
  222. return 2.*PenA_*t + 4.*PenB_*t3 + 6.*PenC_*t5;
  223. }
  224. }
  225. /** second derivative of penalty function term */
  226. inline Number PenObj_2(Number t) const
  227. {
  228. if (B_ == 0.) {
  229. return 1.;
  230. }
  231. else if (t > B_) {
  232. return 0.;
  233. }
  234. else if (t < -B_) {
  235. return 0.;
  236. }
  237. else {
  238. const Number t2 = t*t;
  239. const Number t4 = t2*t2;
  240. return 2.*PenA_ + 12.*PenB_*t2 + 30.*PenC_*t4;
  241. }
  242. }
  243. //@}
  244. /** @name Data for penalty function term */
  245. //@{
  246. Number B_;
  247. Number C_;
  248. Number PenA_;
  249. Number PenB_;
  250. Number PenC_;
  251. //@}
  252. };
  253. /** Class implementating case with convex quadratic penalty function */
  254. class MittelmannBndryCntrlDiri3D_27 : public MittelmannBndryCntrlDiriBase3D_27
  255. {
  256. public:
  257. MittelmannBndryCntrlDiri3D_27()
  258. {}
  259. virtual ~MittelmannBndryCntrlDiri3D_27()
  260. {}
  261. virtual bool InitializeProblem(Index N)
  262. {
  263. if (N<1) {
  264. printf("N has to be at least 1.");
  265. return false;
  266. }
  267. Number alpha = 1e-2;
  268. Number lb_y = -1e20;
  269. Number ub_y = 3.5;
  270. Number lb_u = 0.;
  271. Number ub_u = 10.;
  272. Number d_const = -20.;
  273. Number B = 0.; // convex case (quadratic penalty)
  274. Number C = 0.;
  275. SetBaseParameters(N, alpha, lb_y, ub_y, lb_u, ub_u, d_const, B, C);
  276. return true;
  277. }
  278. protected:
  279. /** Target profile function for y */
  280. virtual Number y_d_cont(Number x1, Number x2, Number x3) const
  281. {
  282. return 3. + 5.*(x1*(x1-1.)*x2*(x2-1.));
  283. }
  284. private:
  285. /**@name hide implicitly defined contructors copy operators */
  286. //@{
  287. MittelmannBndryCntrlDiri3D_27(const MittelmannBndryCntrlDiri3D_27&);
  288. MittelmannBndryCntrlDiri3D_27& operator=(const MittelmannBndryCntrlDiri3D_27&);
  289. //@}
  290. };
  291. /** Class implementating case with nonconvex Beaton-Tukey like penalty
  292. function */
  293. class MittelmannBndryCntrlDiri3D_27BT : public MittelmannBndryCntrlDiriBase3D_27
  294. {
  295. public:
  296. MittelmannBndryCntrlDiri3D_27BT()
  297. {}
  298. virtual ~MittelmannBndryCntrlDiri3D_27BT()
  299. {}
  300. virtual bool InitializeProblem(Index N)
  301. {
  302. if (N<1) {
  303. printf("N has to be at least 1.");
  304. return false;
  305. }
  306. Number alpha = 1e-2;
  307. Number lb_y = -1e20;
  308. Number ub_y = 3.5;
  309. Number lb_u = 0.;
  310. Number ub_u = 10.;
  311. Number d_const = -20.;
  312. Number B = .25; // nonconves case with beaton-tukey-type penalty function
  313. Number C = 0.01;
  314. SetBaseParameters(N, alpha, lb_y, ub_y, lb_u, ub_u, d_const, B, C);
  315. return true;
  316. }
  317. protected:
  318. /** Target profile function for y */
  319. virtual Number y_d_cont(Number x1, Number x2, Number x3) const
  320. {
  321. return 3. + 5.*(x1*(x1-1.)*x2*(x2-1.));
  322. }
  323. private:
  324. /**@name hide implicitly defined contructors copy operators */
  325. //@{
  326. MittelmannBndryCntrlDiri3D_27BT(const MittelmannBndryCntrlDiri3D_27BT&);
  327. MittelmannBndryCntrlDiri3D_27BT& operator=(const MittelmannBndryCntrlDiri3D_27BT&);
  328. //@}
  329. };
  330. #endif