MittelmannDistCntrlNeumA.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. // Copyright (C) 2005, 2006 International Business Machines and others.
  2. // All Rights Reserved.
  3. // This code is published under the Eclipse Public License.
  4. //
  5. // $Id: MittelmannDistCntrlNeumA.hpp 2005 2011-06-06 12:55:16Z stefan $
  6. //
  7. // Authors: Andreas Waechter IBM 2005-10-18
  8. // based on MyNLP.hpp
  9. #ifndef __MITTELMANNDISTRCNTRLNEUMA_HPP__
  10. #define __MITTELMANNDISTRCNTRLNEUMA_HPP__
  11. #include "IpTNLP.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 distributed control problems with homogeneous
  38. * Neumann boundary conditions, as formulated by Hans Mittelmann as
  39. * Examples 4-6 in "Optimization Techniques for Solving Elliptic
  40. * Control Problems with Control and State Constraints. Part 2:
  41. * Distributed Control"
  42. */
  43. class MittelmannDistCntrlNeumABase : public RegisteredTNLP
  44. {
  45. public:
  46. /** Constructor. N is the number of mesh points in one dimension
  47. * (excluding boundary). */
  48. MittelmannDistCntrlNeumABase();
  49. /** Default destructor */
  50. virtual ~MittelmannDistCntrlNeumABase();
  51. /**@name Overloaded from TNLP */
  52. //@{
  53. /** Method to return some info about the nlp */
  54. virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
  55. Index& nnz_h_lag, IndexStyleEnum& index_style);
  56. /** Method to return the bounds for my problem */
  57. virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
  58. Index m, Number* g_l, Number* g_u);
  59. /** Method to return the starting point for the algorithm */
  60. virtual bool get_starting_point(Index n, bool init_x, Number* x,
  61. bool init_z, Number* z_L, Number* z_U,
  62. Index m, bool init_lambda,
  63. Number* lambda);
  64. /** Method to return the objective value */
  65. virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value);
  66. /** Method to return the gradient of the objective */
  67. virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f);
  68. /** Method to return the constraint residuals */
  69. virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g);
  70. /** Method to return:
  71. * 1) The structure of the jacobian (if "values" is NULL)
  72. * 2) The values of the jacobian (if "values" is not NULL)
  73. */
  74. virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
  75. Index m, Index nele_jac, Index* iRow, Index *jCol,
  76. Number* values);
  77. /** Method to return:
  78. * 1) The structure of the hessian of the lagrangian (if "values" is NULL)
  79. * 2) The values of the hessian of the lagrangian (if "values" is not NULL)
  80. */
  81. virtual bool eval_h(Index n, const Number* x, bool new_x,
  82. Number obj_factor, Index m, const Number* lambda,
  83. bool new_lambda, Index nele_hess, Index* iRow,
  84. Index* jCol, Number* values);
  85. //@}
  86. /** Method for returning scaling parameters */
  87. virtual bool get_scaling_parameters(Number& obj_scaling,
  88. bool& use_x_scaling, Index n,
  89. Number* x_scaling,
  90. bool& use_g_scaling, Index m,
  91. Number* g_scaling);
  92. /** @name Solution Methods */
  93. //@{
  94. /** This method is called after the optimization, and could write an
  95. * output file with the optimal profiles */
  96. virtual void finalize_solution(SolverReturn status,
  97. Index n, const Number* x, const Number* z_L, const Number* z_U,
  98. Index m, const Number* g, const Number* lambda,
  99. Number obj_value,
  100. const IpoptData* ip_data,
  101. IpoptCalculatedQuantities* ip_cq);
  102. //@}
  103. protected:
  104. /** Method for setting the internal parameters that define the
  105. * problem. It must be called by the child class in its
  106. * implementation of InitializeParameters. */
  107. void SetBaseParameters(Index N, Number lb_y,
  108. Number ub_y, Number lb_u, Number ub_u,
  109. Number b_0j, Number b_1j, Number b_i0, Number b_i1,
  110. Number u_init);
  111. /**@name Functions that defines a particular instance. */
  112. //@{
  113. /** Target profile function for y (and initial guess function) */
  114. virtual Number y_d_cont(Number x1, Number x2) const =0;
  115. /** Integrant in objective function */
  116. virtual Number fint_cont(Number x1, Number x2, Number y, Number u) const =0;
  117. /** First partial derivative of fint_cont w.r.t. y */
  118. virtual Number fint_cont_dy(Number x1, Number x2, Number y, Number u) const =0;
  119. /** First partial derivative of fint_cont w.r.t. u */
  120. virtual Number fint_cont_du(Number x1, Number x2, Number y, Number u) const =0;
  121. /** Second partial derivative of fint_cont w.r.t. y,y */
  122. virtual Number fint_cont_dydy(Number x1, Number x2, Number y, Number u) const =0;
  123. /** returns true if second partial derivative of fint_cont
  124. * w.r.t. y,y is always zero. */
  125. virtual bool fint_cont_dydy_alwayszero() const =0;
  126. /** Second partial derivative of fint_cont w.r.t. u,u */
  127. virtual Number fint_cont_dudu(Number x1, Number x2, Number y, Number u) const =0;
  128. /** returns true if second partial derivative of fint_cont
  129. * w.r.t. u,u is always zero. */
  130. virtual bool fint_cont_dudu_alwayszero() const =0;
  131. /** Second partial derivative of fint_cont w.r.t. y,u */
  132. virtual Number fint_cont_dydu(Number x1, Number x2, Number y, Number u) const =0;
  133. /** returns true if second partial derivative of fint_cont
  134. * w.r.t. y,u is always zero. */
  135. virtual bool fint_cont_dydu_alwayszero() const =0;
  136. /** Forcing function for the elliptic equation */
  137. virtual Number d_cont(Number x1, Number x2, Number y, Number u) const =0;
  138. /** First partial derivative of forcing function w.r.t. y */
  139. virtual Number d_cont_dy(Number x1, Number x2, Number y, Number u) const =0;
  140. /** First partial derivative of forcing function w.r.t. u */
  141. virtual Number d_cont_du(Number x1, Number x2, Number y, Number u) const =0;
  142. /** Second partial derivative of forcing function w.r.t. y,y */
  143. virtual Number d_cont_dydy(Number x1, Number x2, Number y, Number u) const =0;
  144. /** returns true if second partial derivative of d_cont
  145. * w.r.t. y,y is always zero. */
  146. virtual bool d_cont_dydy_alwayszero() const =0;
  147. /** Second partial derivative of forcing function w.r.t. u,u */
  148. virtual Number d_cont_dudu(Number x1, Number x2, Number y, Number u) const =0;
  149. /** returns true if second partial derivative of d_cont
  150. * w.r.t. y,y is always zero. */
  151. virtual bool d_cont_dudu_alwayszero() const =0;
  152. /** Second partial derivative of forcing function w.r.t. y,u */
  153. virtual Number d_cont_dydu(Number x1, Number x2, Number y, Number u) const =0;
  154. /** returns true if second partial derivative of d_cont
  155. * w.r.t. y,u is always zero. */
  156. virtual bool d_cont_dydu_alwayszero() const =0;
  157. //@}
  158. private:
  159. /**@name Methods to block default compiler methods.
  160. * The compiler automatically generates the following three methods.
  161. * Since the default compiler implementation is generally not what
  162. * you want (for all but the most simple classes), we usually
  163. * put the declarations of these methods in the private section
  164. * and never implement them. This prevents the compiler from
  165. * implementing an incorrect "default" behavior without us
  166. * knowing. (See Scott Meyers book, "Effective C++")
  167. *
  168. */
  169. //@{
  170. MittelmannDistCntrlNeumABase(const MittelmannDistCntrlNeumABase&);
  171. MittelmannDistCntrlNeumABase& operator=(const MittelmannDistCntrlNeumABase&);
  172. //@}
  173. /**@name Problem specification */
  174. //@{
  175. /** Number of mesh points in one dimension (excluding boundary) */
  176. Index N_;
  177. /** Step size */
  178. Number h_;
  179. /** h_ squaredd */
  180. Number hh_;
  181. /** overall lower bound on y */
  182. Number lb_y_;
  183. /** overall upper bound on y */
  184. Number ub_y_;
  185. /** overall lower bound on u */
  186. Number lb_u_;
  187. /** overall upper bound on u */
  188. Number ub_u_;
  189. /** Value of beta function (in Neumann boundary condition) for
  190. * (0,x2) bounray */
  191. Number b_0j_;
  192. /** Value of beta function (in Neumann boundary condition) for
  193. * (1,x2) bounray */
  194. Number b_1j_;
  195. /** Value of beta function (in Neumann boundary condition) for
  196. * (x1,0) bounray */
  197. Number b_i0_;
  198. /** Value of beta function (in Neumann boundary condition) for
  199. * (x1,1) bounray */
  200. Number b_i1_;
  201. /** Initial value for the constrols u */
  202. Number u_init_;
  203. /** Array for the target profile for y */
  204. Number* y_d_;
  205. //@}
  206. /**@name Auxilliary methods */
  207. //@{
  208. /** Translation of mesh point indices to NLP variable indices for
  209. * y(x_ij) */
  210. inline Index y_index(Index i, Index j) const
  211. {
  212. return j + (N_+2)*i;
  213. }
  214. /** Translation of mesh point indices to NLP variable indices for
  215. * u(x_ij) */
  216. inline Index u_index(Index i, Index j) const
  217. {
  218. return (N_+2)*(N_+2) + (j-1) + (N_)*(i-1);
  219. }
  220. /** Translation of interior mesh point indices to the corresponding
  221. * PDE constraint number */
  222. inline Index pde_index(Index i, Index j) const
  223. {
  224. return (j-1) + N_*(i-1);
  225. }
  226. /** Compute the grid coordinate for given index in x1 direction */
  227. inline Number x1_grid(Index i) const
  228. {
  229. return h_*(Number)i;
  230. }
  231. /** Compute the grid coordinate for given index in x2 direction */
  232. inline Number x2_grid(Index i) const
  233. {
  234. return h_*(Number)i;
  235. }
  236. //@}
  237. };
  238. /** Class implementating Example 4 */
  239. class MittelmannDistCntrlNeumA1 : public MittelmannDistCntrlNeumABase
  240. {
  241. public:
  242. MittelmannDistCntrlNeumA1()
  243. :
  244. pi_(4.*atan(1.)),
  245. alpha_(0.001)
  246. {}
  247. virtual ~MittelmannDistCntrlNeumA1()
  248. {}
  249. virtual bool InitializeProblem(Index N)
  250. {
  251. if (N<1) {
  252. printf("N has to be at least 1.");
  253. return false;
  254. }
  255. Number lb_y = -1e20;
  256. Number ub_y = 0.371;
  257. Number lb_u = -8.;
  258. Number ub_u = 9.;
  259. Number b_0j = 1.;
  260. Number b_1j = 1.;
  261. Number b_i0 = 1.;
  262. Number b_i1 = 1.;
  263. Number u_init = (ub_u+lb_u)/2.;
  264. SetBaseParameters(N, lb_y, ub_y, lb_u, ub_u, b_0j, b_1j, b_i0, b_i1, u_init);
  265. return true;
  266. }
  267. protected:
  268. /** Target profile function for y */
  269. virtual Number y_d_cont(Number x1, Number x2) const
  270. {
  271. return sin(2.*pi_*x1)*sin(2.*pi_*x2);
  272. }
  273. /** Integrant in objective function */
  274. virtual Number fint_cont(Number x1, Number x2, Number y, Number u) const
  275. {
  276. Number diff_y = y-y_d_cont(x1,x2);
  277. return 0.5*(diff_y*diff_y + alpha_*u*u);
  278. }
  279. /** First partial derivative of fint_cont w.r.t. y */
  280. virtual Number fint_cont_dy(Number x1, Number x2, Number y, Number u) const
  281. {
  282. return y-y_d_cont(x1,x2);
  283. }
  284. /** First partial derivative of fint_cont w.r.t. u */
  285. virtual Number fint_cont_du(Number x1, Number x2, Number y, Number u) const
  286. {
  287. return alpha_*u;
  288. }
  289. /** Second partial derivative of fint_cont w.r.t. y,y */
  290. virtual Number fint_cont_dydy(Number x1, Number x2, Number y, Number u) const
  291. {
  292. return 1.;
  293. }
  294. /** returns true if second partial derivative of fint_cont
  295. * w.r.t. y,y is always zero. */
  296. virtual bool fint_cont_dydy_alwayszero() const
  297. {
  298. return false;
  299. }
  300. /** Second partial derivative of fint_cont w.r.t. u,u */
  301. virtual Number fint_cont_dudu(Number x1, Number x2, Number y, Number u) const
  302. {
  303. return alpha_;
  304. }
  305. /** returns true if second partial derivative of fint_cont
  306. * w.r.t. u,u is always zero. */
  307. virtual bool fint_cont_dudu_alwayszero() const
  308. {
  309. return false;
  310. }
  311. /** Second partial derivative of fint_cont w.r.t. y,u */
  312. virtual Number fint_cont_dydu(Number x1, Number x2, Number y, Number u) const
  313. {
  314. return 0.;
  315. }
  316. /** returns true if second partial derivative of fint_cont
  317. * w.r.t. y,u is always zero. */
  318. virtual bool fint_cont_dydu_alwayszero() const
  319. {
  320. return true;
  321. }
  322. /** Forcing function for the elliptic equation */
  323. virtual Number d_cont(Number x1, Number x2, Number y, Number u) const
  324. {
  325. return -exp(y) - u;
  326. }
  327. /** First partial derivative of forcing function w.r.t. y */
  328. virtual Number d_cont_dy(Number x1, Number x2, Number y, Number u) const
  329. {
  330. return -exp(y);
  331. }
  332. /** First partial derivative of forcing function w.r.t. u */
  333. virtual Number d_cont_du(Number x1, Number x2, Number y, Number u) const
  334. {
  335. return -1.;
  336. }
  337. /** Second partial derivative of forcing function w.r.t y,y */
  338. virtual Number d_cont_dydy(Number x1, Number x2, Number y, Number u) const
  339. {
  340. return -exp(y);
  341. }
  342. /** returns true if second partial derivative of d_cont
  343. * w.r.t. y,y is always zero. */
  344. virtual bool d_cont_dydy_alwayszero() const
  345. {
  346. return false;
  347. }
  348. /** Second partial derivative of forcing function w.r.t. u,u */
  349. virtual Number d_cont_dudu(Number x1, Number x2, Number y, Number u) const
  350. {
  351. return 0.;
  352. }
  353. /** returns true if second partial derivative of d_cont
  354. * w.r.t. y,y is always zero. */
  355. virtual bool d_cont_dudu_alwayszero() const
  356. {
  357. return true;
  358. }
  359. /** Second partial derivative of forcing function w.r.t. y,u */
  360. virtual Number d_cont_dydu(Number x1, Number x2, Number y, Number u) const
  361. {
  362. return 0.;
  363. }
  364. /** returns true if second partial derivative of d_cont
  365. * w.r.t. y,u is always zero. */
  366. virtual bool d_cont_dydu_alwayszero() const
  367. {
  368. return true;
  369. }
  370. private:
  371. /**@name hide implicitly defined contructors copy operators */
  372. //@{
  373. MittelmannDistCntrlNeumA1(const MittelmannDistCntrlNeumA1&);
  374. MittelmannDistCntrlNeumA1& operator=(const MittelmannDistCntrlNeumA1&);
  375. //@}
  376. /** Value of pi (made available for convenience) */
  377. const Number pi_;
  378. /** Value for parameter alpha in objective functin */
  379. const Number alpha_;
  380. };
  381. /** Class implementating Example 5 */
  382. class MittelmannDistCntrlNeumA2 : public MittelmannDistCntrlNeumABase
  383. {
  384. public:
  385. MittelmannDistCntrlNeumA2()
  386. :
  387. pi_(4.*atan(1.))
  388. {}
  389. virtual ~MittelmannDistCntrlNeumA2()
  390. {}
  391. virtual bool InitializeProblem(Index N)
  392. {
  393. if (N<1) {
  394. printf("N has to be at least 1.");
  395. return false;
  396. }
  397. Number lb_y = -1e20;
  398. Number ub_y = 0.371;
  399. Number lb_u = -8.;
  400. Number ub_u = 9.;
  401. Number b_0j = 1.;
  402. Number b_1j = 1.;
  403. Number b_i0 = 1.;
  404. Number b_i1 = 1.;
  405. Number u_init = (ub_u+lb_u)/2.;
  406. SetBaseParameters(N, lb_y, ub_y, lb_u, ub_u, b_0j, b_1j, b_i0, b_i1, u_init);
  407. return true;
  408. }
  409. protected:
  410. /** Target profile function for y */
  411. virtual Number y_d_cont(Number x1, Number x2) const
  412. {
  413. return sin(2.*pi_*x1)*sin(2.*pi_*x2);
  414. }
  415. /** Integrant in objective function */
  416. virtual Number fint_cont(Number x1, Number x2, Number y, Number u) const
  417. {
  418. Number diff_y = y-y_d_cont(x1,x2);
  419. return 0.5*diff_y*diff_y;
  420. }
  421. /** First partial derivative of fint_cont w.r.t. y */
  422. virtual Number fint_cont_dy(Number x1, Number x2, Number y, Number u) const
  423. {
  424. return y-y_d_cont(x1,x2);
  425. }
  426. /** First partial derivative of fint_cont w.r.t. u */
  427. virtual Number fint_cont_du(Number x1, Number x2, Number y, Number u) const
  428. {
  429. return 0.;
  430. }
  431. /** Second partial derivative of fint_cont w.r.t. y,y */
  432. virtual Number fint_cont_dydy(Number x1, Number x2, Number y, Number u) const
  433. {
  434. return 1.;
  435. }
  436. /** returns true if second partial derivative of fint_cont
  437. * w.r.t. y,y is always zero. */
  438. virtual bool fint_cont_dydy_alwayszero() const
  439. {
  440. return false;
  441. }
  442. /** Second partial derivative of fint_cont w.r.t. u,u */
  443. virtual Number fint_cont_dudu(Number x1, Number x2, Number y, Number u) const
  444. {
  445. return 0.;
  446. }
  447. /** returns true if second partial derivative of fint_cont
  448. * w.r.t. u,u is always zero. */
  449. virtual bool fint_cont_dudu_alwayszero() const
  450. {
  451. return true;
  452. }
  453. /** Second partial derivative of fint_cont w.r.t. y,u */
  454. virtual Number fint_cont_dydu(Number x1, Number x2, Number y, Number u) const
  455. {
  456. return 0.;
  457. }
  458. /** returns true if second partial derivative of fint_cont
  459. * w.r.t. y,u is always zero. */
  460. virtual bool fint_cont_dydu_alwayszero() const
  461. {
  462. return true;
  463. }
  464. /** Forcing function for the elliptic equation */
  465. virtual Number d_cont(Number x1, Number x2, Number y, Number u) const
  466. {
  467. return -exp(y) - u;
  468. }
  469. /** First partial derivative of forcing function w.r.t. y */
  470. virtual Number d_cont_dy(Number x1, Number x2, Number y, Number u) const
  471. {
  472. return -exp(y);
  473. }
  474. /** First partial derivative of forcing function w.r.t. u */
  475. virtual Number d_cont_du(Number x1, Number x2, Number y, Number u) const
  476. {
  477. return -1.;
  478. }
  479. /** Second partial derivative of forcing function w.r.t y,y */
  480. virtual Number d_cont_dydy(Number x1, Number x2, Number y, Number u) const
  481. {
  482. return -exp(y);
  483. }
  484. /** returns true if second partial derivative of d_cont
  485. * w.r.t. y,y is always zero. */
  486. virtual bool d_cont_dydy_alwayszero() const
  487. {
  488. return false;
  489. }
  490. /** Second partial derivative of forcing function w.r.t. u,u */
  491. virtual Number d_cont_dudu(Number x1, Number x2, Number y, Number u) const
  492. {
  493. return 0.;
  494. }
  495. /** returns true if second partial derivative of d_cont
  496. * w.r.t. y,y is always zero. */
  497. virtual bool d_cont_dudu_alwayszero() const
  498. {
  499. return true;
  500. }
  501. /** Second partial derivative of forcing function w.r.t. y,u */
  502. virtual Number d_cont_dydu(Number x1, Number x2, Number y, Number u) const
  503. {
  504. return 0.;
  505. }
  506. /** returns true if second partial derivative of d_cont
  507. * w.r.t. y,u is always zero. */
  508. virtual bool d_cont_dydu_alwayszero() const
  509. {
  510. return true;
  511. }
  512. private:
  513. /**@name hide implicitly defined contructors copy operators */
  514. //@{
  515. MittelmannDistCntrlNeumA2(const MittelmannDistCntrlNeumA2&);
  516. MittelmannDistCntrlNeumA2& operator=(const MittelmannDistCntrlNeumA2&);
  517. //@}
  518. /** Value of pi (made available for convenience) */
  519. const Number pi_;
  520. };
  521. /** Class implementating Example 6 */
  522. class MittelmannDistCntrlNeumA3 : public MittelmannDistCntrlNeumABase
  523. {
  524. public:
  525. MittelmannDistCntrlNeumA3()
  526. :
  527. pi_(4.*atan(1.)),
  528. M_(1.),
  529. K_(0.8),
  530. b_(1.)
  531. {}
  532. virtual ~MittelmannDistCntrlNeumA3()
  533. {}
  534. virtual bool InitializeProblem(Index N)
  535. {
  536. if (N<1) {
  537. printf("N has to be at least 1.");
  538. return false;
  539. }
  540. Number lb_y = 3.;//-1e20;
  541. Number ub_y = 6.09;
  542. Number lb_u = 1.4;
  543. Number ub_u = 1.6;
  544. Number b_0j = 1.;
  545. Number b_1j = 0.;
  546. Number b_i0 = 1.;
  547. Number b_i1 = 0.;
  548. Number u_init = (ub_u+lb_u)/2.;
  549. SetBaseParameters(N, lb_y, ub_y, lb_u, ub_u, b_0j, b_1j, b_i0, b_i1, u_init);
  550. return true;
  551. }
  552. protected:
  553. /** Profile function for initial y */
  554. virtual Number y_d_cont(Number x1, Number x2) const
  555. {
  556. return 6.;
  557. }
  558. /** Integrant in objective function */
  559. virtual Number fint_cont(Number x1, Number x2, Number y, Number u) const
  560. {
  561. return u*(M_*u - K_*y);
  562. }
  563. /** First partial derivative of fint_cont w.r.t. y */
  564. virtual Number fint_cont_dy(Number x1, Number x2, Number y, Number u) const
  565. {
  566. return -K_*u;
  567. }
  568. /** First partial derivative of fint_cont w.r.t. u */
  569. virtual Number fint_cont_du(Number x1, Number x2, Number y, Number u) const
  570. {
  571. return 2.*M_*u - K_*y;
  572. }
  573. /** Second partial derivative of fint_cont w.r.t. y,y */
  574. virtual Number fint_cont_dydy(Number x1, Number x2, Number y, Number u) const
  575. {
  576. return 0.;
  577. }
  578. /** returns true if second partial derivative of fint_cont
  579. * w.r.t. y,y is always zero. */
  580. virtual bool fint_cont_dydy_alwayszero() const
  581. {
  582. return true;
  583. }
  584. /** Second partial derivative of fint_cont w.r.t. u,u */
  585. virtual Number fint_cont_dudu(Number x1, Number x2, Number y, Number u) const
  586. {
  587. return 2.*M_;
  588. }
  589. /** returns true if second partial derivative of fint_cont
  590. * w.r.t. u,u is always zero. */
  591. virtual bool fint_cont_dudu_alwayszero() const
  592. {
  593. return false;
  594. }
  595. /** Second partial derivative of fint_cont w.r.t. y,u */
  596. virtual Number fint_cont_dydu(Number x1, Number x2, Number y, Number u) const
  597. {
  598. return -K_;
  599. }
  600. /** returns true if second partial derivative of fint_cont
  601. * w.r.t. y,u is always zero. */
  602. virtual bool fint_cont_dydu_alwayszero() const
  603. {
  604. return false;
  605. }
  606. /** Forcing function for the elliptic equation */
  607. virtual Number d_cont(Number x1, Number x2, Number y, Number u) const
  608. {
  609. return y*(u + b_*y - a(x1,x2));
  610. }
  611. /** First partial derivative of forcing function w.r.t. y */
  612. virtual Number d_cont_dy(Number x1, Number x2, Number y, Number u) const
  613. {
  614. return (u + 2.*b_*y -a(x1,x2));
  615. }
  616. /** First partial derivative of forcing function w.r.t. u */
  617. virtual Number d_cont_du(Number x1, Number x2, Number y, Number u) const
  618. {
  619. return y;
  620. }
  621. /** Second partial derivative of forcing function w.r.t y,y */
  622. virtual Number d_cont_dydy(Number x1, Number x2, Number y, Number u) const
  623. {
  624. return 2.*b_;
  625. }
  626. /** returns true if second partial derivative of d_cont
  627. * w.r.t. y,y is always zero. */
  628. virtual bool d_cont_dydy_alwayszero() const
  629. {
  630. return false;
  631. }
  632. /** Second partial derivative of forcing function w.r.t. u,u */
  633. virtual Number d_cont_dudu(Number x1, Number x2, Number y, Number u) const
  634. {
  635. return 0.;
  636. }
  637. /** returns true if second partial derivative of d_cont
  638. * w.r.t. y,y is always zero. */
  639. virtual bool d_cont_dudu_alwayszero() const
  640. {
  641. return true;
  642. }
  643. /** Second partial derivative of forcing function w.r.t. y,u */
  644. virtual Number d_cont_dydu(Number x1, Number x2, Number y, Number u) const
  645. {
  646. return 1.;
  647. }
  648. /** returns true if second partial derivative of d_cont
  649. * w.r.t. y,u is always zero. */
  650. virtual bool d_cont_dydu_alwayszero() const
  651. {
  652. return false;
  653. }
  654. private:
  655. /**@name hide implicitly defined contructors copy operators */
  656. //@{
  657. MittelmannDistCntrlNeumA3(const MittelmannDistCntrlNeumA3&);
  658. MittelmannDistCntrlNeumA3& operator=(const MittelmannDistCntrlNeumA3&);
  659. //@}
  660. /** Value of pi (made available for convenience) */
  661. const Number pi_;
  662. /*@name constrants appearing in problem formulation */
  663. //@{
  664. const Number M_;
  665. const Number K_;
  666. const Number b_;
  667. //@}
  668. //* Auxiliary function for state equation */
  669. inline Number a(Number x1, Number x2) const
  670. {
  671. return 7. + 4.*sin(2.*pi_*x1*x2);
  672. }
  673. };
  674. #endif