MittelmannBndryCntrlDiri3D_27.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  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.cpp 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.cpp for 3-dim problem
  10. #include "MittelmannBndryCntrlDiri3D_27.hpp"
  11. #ifdef HAVE_CASSERT
  12. # include <cassert>
  13. #else
  14. # ifdef HAVE_ASSERT_H
  15. # include <assert.h>
  16. # else
  17. # error "don't have header file for assert"
  18. # endif
  19. #endif
  20. using namespace Ipopt;
  21. /* Constructor. */
  22. MittelmannBndryCntrlDiriBase3D_27::MittelmannBndryCntrlDiriBase3D_27()
  23. :
  24. y_d_(NULL)
  25. {}
  26. MittelmannBndryCntrlDiriBase3D_27::~MittelmannBndryCntrlDiriBase3D_27()
  27. {
  28. delete [] y_d_;
  29. }
  30. void
  31. MittelmannBndryCntrlDiriBase3D_27::SetBaseParameters(Index N, Number alpha, Number lb_y,
  32. Number ub_y, Number lb_u, Number ub_u,
  33. Number d_const, Number B, Number C)
  34. {
  35. N_ = N;
  36. h_ = 1./(N+1);
  37. hh_ = h_*h_;
  38. hhh_ = hh_*h_;
  39. lb_y_ = lb_y;
  40. ub_y_ = ub_y;
  41. lb_u_ = lb_u;
  42. ub_u_ = ub_u;
  43. d_const_ = d_const;
  44. alpha_ = alpha;
  45. B_ = B;
  46. C_ = C;
  47. PenA_ = 1.5 - 1.125*C_/B_;
  48. PenB_ = 1.75*C_/pow(B_,3) - 1.5/(B_*B_);
  49. PenC_ = 0.5/pow(B_,4) - 0.625*C_/pow(B_,5);
  50. // Initialize the target profile variables
  51. delete [] y_d_;
  52. y_d_ = new Number[(N_+2)*(N_+2)*(N_+2)];
  53. for (Index k=0; k<= N_+1; k++) {
  54. for (Index j=0; j<= N_+1; j++) {
  55. for (Index i=0; i<= N_+1; i++) {
  56. y_d_[y_index(i,j,k)] = y_d_cont(x1_grid(i),x2_grid(j),x3_grid(k));
  57. }
  58. }
  59. }
  60. }
  61. bool MittelmannBndryCntrlDiriBase3D_27::get_nlp_info(
  62. Index& n, Index& m, Index& nnz_jac_g,
  63. Index& nnz_h_lag, IndexStyleEnum& index_style)
  64. {
  65. // We for each of the N_+2 times N_+2 times N_+2 mesh points we have
  66. // the value of the functions y, including the control parameters on
  67. // the boundary
  68. n = (N_+2)*(N_+2)*(N_+2);
  69. // For each of the N_ times N_ times N_ interior mesh points we have the
  70. // discretized PDE.
  71. m = N_*N_*N_;
  72. // y(i-1,j-1,k-1), y(i,j-1,k-1), y(i+1,j-1,k-1)
  73. // y(i-1,j ,k-1), y(i,j ,k-1), y(i+1,j, k-1)
  74. // y(i-1,j+1,k-1), y(i,j+1,k-1), y(i+1,j+1,k-1),
  75. // y(i-1,j-1,k), y(i,j-1,k), y(i+1,j-1,k)
  76. // y(i-1,j ,k), y(i,j ,k), y(i+1,j, k)
  77. // y(i-1,j+1,k), y(i,j+1,k), y(i+1,j+1,k),
  78. // y(i-1,j-1,k+1), y(i,j-1,k+1), y(i+1,j-1,k+1)
  79. // y(i-1,j ,k+1), y(i,j ,k+1), y(i+1,j, k+1)
  80. // y(i-1,j+1,k+1), y(i,j+1,k+1), y(i+1,j+1,k+1),
  81. // of the N_*N_*N_ discretized PDEs
  82. nnz_jac_g = 27*N_*N_*N_;
  83. // diagonal entry for each y(i,j) in the interior
  84. nnz_h_lag = N_*N_*N_;
  85. if (alpha_>0.) {
  86. // and one entry for u(i,j) in the bundary if alpha is not zero
  87. nnz_h_lag += 6*N_*N_;
  88. }
  89. // We use the C indexing style for row/col entries (corresponding to
  90. // the C notation, starting at 0)
  91. index_style = C_STYLE;
  92. return true;
  93. }
  94. bool
  95. MittelmannBndryCntrlDiriBase3D_27::get_bounds_info(Index n, Number* x_l, Number* x_u,
  96. Index m, Number* g_l, Number* g_u)
  97. {
  98. // Set overall bounds on the y variables
  99. for (Index i=0; i<=N_+1; i++) {
  100. for (Index j=0; j<=N_+1; j++) {
  101. for (Index k=0; k<=N_+1; k++) {
  102. Index iy = y_index(i,j,k);
  103. x_l[iy] = lb_y_;
  104. x_u[iy] = ub_y_;
  105. }
  106. }
  107. }
  108. // Set the overall 3D bounds on the control variables
  109. for (Index i=0; i<=N_+1; i++) {
  110. for (Index j=0; j<=N_+1; j++) {
  111. Index iu = y_index(i,j,0);
  112. x_l[iu] = lb_u_;
  113. x_u[iu] = ub_u_;
  114. }
  115. }
  116. for (Index i=0; i<=N_+1; i++) {
  117. for (Index j=0; j<=N_+1; j++) {
  118. Index iu = y_index(i,j,N_+1);
  119. x_l[iu] = lb_u_;
  120. x_u[iu] = ub_u_;
  121. }
  122. }
  123. for (Index i=0; i<=N_+1; i++) {
  124. for (Index k=0; k<=N_+1; k++) {
  125. Index iu = y_index(i,0,k);
  126. x_l[iu] = lb_u_;
  127. x_u[iu] = ub_u_;
  128. }
  129. }
  130. for (Index i=0; i<=N_+1; i++) {
  131. for (Index k=0; k<=N_+1; k++) {
  132. Index iu = y_index(i,N_+1,k);
  133. x_l[iu] = lb_u_;
  134. x_u[iu] = ub_u_;
  135. }
  136. }
  137. for (Index j=0; j<=N_+1; j++) {
  138. for (Index k=0; k<=N_+1; k++) {
  139. Index iu = y_index(0,j,k);
  140. x_l[iu] = lb_u_;
  141. x_u[iu] = ub_u_;
  142. }
  143. }
  144. for (Index j=0; j<=N_+1; j++) {
  145. for (Index k=0; k<=N_+1; k++) {
  146. Index iu = y_index(N_+1,j,k);
  147. x_l[iu] = lb_u_;
  148. x_u[iu] = ub_u_;
  149. }
  150. }
  151. // The values of y on the corners doens't appear anywhere, so we fix
  152. // them to zero
  153. for (Index j=0; j<=N_+1; j++) {
  154. x_l[y_index(0,j,0)] = x_u[y_index(0,j,0)] = 0.;
  155. x_l[y_index(0,j,N_+1)] = x_u[y_index(0,j,N_+1)] = 0.;
  156. x_l[y_index(N_+1,j,0)] = x_u[y_index(N_+1,j,0)] = 0.;
  157. x_l[y_index(N_+1,j,N_+1)] = x_u[y_index(N_+1,j,N_+1)] = 0.;
  158. }
  159. for (Index k=0; k<=N_+1; k++) {
  160. x_l[y_index(0,0,k)] = x_u[y_index(0,0,k)] = 0.;
  161. x_l[y_index(0,N_+1,k)] = x_u[y_index(0,N_+1,k)] = 0.;
  162. x_l[y_index(N_+1,0,k)] = x_u[y_index(N_+1,0,k)] = 0.;
  163. x_l[y_index(N_+1,N_+1,k)] = x_u[y_index(N_+1,N_+1,k)] = 0.;
  164. }
  165. for (Index i=0; i<=N_+1; i++) {
  166. x_l[y_index(i,0,0)] = x_u[y_index(i,0,0)] = 0.;
  167. x_l[y_index(i,0,N_+1)] = x_u[y_index(i,0,N_+1)] = 0.;
  168. x_l[y_index(i,N_+1,0)] = x_u[y_index(i,N_+1,0)] = 0.;
  169. x_l[y_index(i,N_+1,N_+1)] = x_u[y_index(i,N_+1,N_+1)] = 0.;
  170. }
  171. // all discretized PDE constraints have right hand side equal to
  172. // minus the constant value of the function d
  173. for (Index i=0; i<m; i++) {
  174. g_l[i] = -hh_*d_const_;
  175. g_u[i] = -hh_*d_const_;
  176. }
  177. return true;
  178. }
  179. bool
  180. MittelmannBndryCntrlDiriBase3D_27::get_starting_point(Index n, bool init_x, Number* x,
  181. bool init_z, Number* z_L, Number* z_U,
  182. Index m, bool init_lambda,
  183. Number* lambda)
  184. {
  185. // Here, we assume we only have starting values for x, if you code
  186. // your own NLP, you can provide starting values for the others if
  187. // you wish.
  188. assert(init_x == true);
  189. assert(init_z == false);
  190. assert(init_lambda == false);
  191. // set all y's to the perfect match with y_d
  192. for (Index i=0; i<= N_+1; i++) {
  193. for (Index j=0; j<= N_+1; j++) {
  194. for (Index k=0; k<= N_+1; k++) {
  195. x[y_index(i,j,k)] = y_d_[y_index(i,j,k)]; // 0 in AMPL model
  196. }
  197. }
  198. }
  199. Number umid = (ub_u_ + lb_u_)/2.;
  200. for (Index i=0; i<=N_+1; i++) {
  201. for (Index j=0; j<=N_+1; j++) {
  202. Index iu = y_index(i,j,0);
  203. x[iu] = umid;
  204. }
  205. }
  206. for (Index i=0; i<=N_+1; i++) {
  207. for (Index j=0; j<=N_+1; j++) {
  208. Index iu = y_index(i,j,N_+1);
  209. x[iu] = umid;
  210. }
  211. }
  212. for (Index i=0; i<=N_+1; i++) {
  213. for (Index k=0; k<=N_+1; k++) {
  214. Index iu = y_index(i,0,k);
  215. x[iu] = umid;
  216. }
  217. }
  218. for (Index i=0; i<=N_+1; i++) {
  219. for (Index k=0; k<=N_+1; k++) {
  220. Index iu = y_index(i,N_+1,k);
  221. x[iu] = umid;
  222. }
  223. }
  224. for (Index k=0; k<=N_+1; k++) {
  225. for (Index j=0; j<=N_+1; j++) {
  226. Index iu = y_index(0,j,k);
  227. x[iu] = umid;
  228. }
  229. }
  230. for (Index k=0; k<=N_+1; k++) {
  231. for (Index j=0; j<=N_+1; j++) {
  232. Index iu = y_index(N_+1,j,k);
  233. x[iu] = umid;
  234. }
  235. }
  236. return true;
  237. }
  238. bool
  239. MittelmannBndryCntrlDiriBase3D_27::get_scaling_parameters(Number& obj_scaling,
  240. bool& use_x_scaling, Index n, Number* x_scaling,
  241. bool& use_g_scaling, Index m, Number* g_scaling)
  242. {
  243. obj_scaling = 1./hhh_;
  244. use_x_scaling = false;
  245. use_g_scaling = false;
  246. return true;
  247. }
  248. bool
  249. MittelmannBndryCntrlDiriBase3D_27::eval_f(Index n, const Number* x,
  250. bool new_x, Number& obj_value)
  251. {
  252. // return the value of the objective function
  253. obj_value = 0.;
  254. // First the integration of y-td over the interior
  255. for (Index i=1; i<=N_; i++) {
  256. for (Index j=1; j<= N_; j++) {
  257. for (Index k=1; k<= N_; k++) {
  258. Index iy = y_index(i,j,k);
  259. Number tmp = x[iy] - y_d_[iy];
  260. obj_value += PenObj(tmp);
  261. //obj_value += tmp*tmp;
  262. }
  263. }
  264. }
  265. obj_value *= hhh_;
  266. // Now the integration of u over the boundary
  267. if (alpha_>0.) {
  268. Number usum = 0.;
  269. for (Index i=1; i<=N_; i++) {
  270. for (Index j=1; j<=N_; j++) {
  271. Index iu = y_index(i,j,0);
  272. usum += x[iu]*x[iu];
  273. }
  274. }
  275. for (Index i=1; i<=N_; i++) {
  276. for (Index j=1; j<=N_; j++) {
  277. Index iu = y_index(i,j,N_+1);
  278. usum += x[iu]*x[iu];
  279. }
  280. }
  281. for (Index k=1; k<=N_; k++) {
  282. for (Index j=1; j<=N_; j++) {
  283. Index iu = y_index(0,j,k);
  284. usum += x[iu]*x[iu];
  285. }
  286. }
  287. for (Index k=1; k<=N_; k++) {
  288. for (Index j=1; j<=N_; j++) {
  289. Index iu = y_index(N_+1,j,k);
  290. usum += x[iu]*x[iu];
  291. }
  292. }
  293. for (Index i=1; i<=N_; i++) {
  294. for (Index k=1; k<=N_; k++) {
  295. Index iu = y_index(i,0,k);
  296. usum += x[iu]*x[iu];
  297. }
  298. }
  299. for (Index i=1; i<=N_; i++) {
  300. for (Index k=1; k<=N_; k++) {
  301. Index iu = y_index(i,N_+1,k);
  302. usum += x[iu]*x[iu];
  303. }
  304. }
  305. obj_value += alpha_*hh_*0.5*usum;
  306. }
  307. return true;
  308. }
  309. bool
  310. MittelmannBndryCntrlDiriBase3D_27::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
  311. {
  312. // return the gradient of the objective function grad_{x} f(x)
  313. // now let's take care of the nonzero values coming from the
  314. // integrant over the interior
  315. for (Index i=1; i<=N_; i++) {
  316. for (Index j=1; j<= N_; j++) {
  317. for (Index k=1; k<= N_; k++) {
  318. Index iy = y_index(i,j,k);
  319. grad_f[iy] = hhh_*PenObj_1(x[iy] - y_d_[iy]);
  320. }
  321. }
  322. }
  323. // The values for variables on the boundary
  324. if (alpha_>0.) {
  325. for (Index i=1; i<= N_; i++) {
  326. for (Index j=1; j<= N_; j++) {
  327. Index iu = y_index(i,j,0);
  328. grad_f[iu] = alpha_*hh_*x[iu];
  329. }
  330. }
  331. for (Index i=1; i<= N_; i++) {
  332. for (Index j=1; j<= N_; j++) {
  333. Index iu = y_index(i,j,N_+1);
  334. grad_f[iu] = alpha_*hh_*x[iu];
  335. }
  336. }
  337. for (Index k=1; k<= N_; k++) {
  338. for (Index j=1; j<= N_; j++) {
  339. Index iu = y_index(0,j,k);
  340. grad_f[iu] = alpha_*hh_*x[iu];
  341. }
  342. }
  343. for (Index k=1; k<= N_; k++) {
  344. for (Index j=1; j<= N_; j++) {
  345. Index iu = y_index(N_+1,j,k);
  346. grad_f[iu] = alpha_*hh_*x[iu];
  347. }
  348. }
  349. for (Index i=1; i<= N_; i++) {
  350. for (Index k=1; k<= N_; k++) {
  351. Index iu = y_index(i,0,k);
  352. grad_f[iu] = alpha_*hh_*x[iu];
  353. }
  354. }
  355. for (Index i=1; i<= N_; i++) {
  356. for (Index k=1; k<= N_; k++) {
  357. Index iu = y_index(i,N_+1,k);
  358. grad_f[iu] = alpha_*hh_*x[iu];
  359. }
  360. }
  361. }
  362. else {
  363. for (Index i=1; i<= N_; i++) {
  364. for (Index j=1; j<= N_; j++) {
  365. grad_f[y_index(i,j,0)] = 0.;
  366. }
  367. }
  368. for (Index i=1; i<= N_; i++) {
  369. for (Index j=1; j<= N_; j++) {
  370. grad_f[y_index(i,j,N_+1)] = 0.;
  371. }
  372. }
  373. for (Index k=1; k<= N_; k++) {
  374. for (Index j=1; j<= N_; j++) {
  375. grad_f[y_index(0,j,k)] = 0.;
  376. }
  377. }
  378. for (Index k=1; k<= N_; k++) {
  379. for (Index j=1; j<= N_; j++) {
  380. grad_f[y_index(N_+1,j,k)] = 0.;
  381. }
  382. }
  383. for (Index i=1; i<= N_; i++) {
  384. for (Index k=1; k<= N_; k++) {
  385. grad_f[y_index(i,0,k)] = 0.;
  386. }
  387. }
  388. for (Index i=1; i<= N_; i++) {
  389. for (Index k=1; k<= N_; k++) {
  390. grad_f[y_index(i,N_+1,k)] = 0.;
  391. }
  392. }
  393. }
  394. // Nothing on the corner points
  395. for (Index i=0; i<= N_+1; i++) {
  396. grad_f[y_index(i,0 ,0 )] = 0.;
  397. grad_f[y_index(i,0 ,N_+1)] = 0.;
  398. grad_f[y_index(i,N_+1,0 )] = 0.;
  399. grad_f[y_index(i,N_+1,N_+1)] = 0.;
  400. }
  401. for (Index j=0; j<= N_+1; j++) {
  402. grad_f[y_index(0, j,0 )] = 0.;
  403. grad_f[y_index(N_+1,j,0 )] = 0.;
  404. grad_f[y_index(0, j,N_+1)] = 0.;
  405. grad_f[y_index(N_+1,j,N_+1)] = 0.;
  406. }
  407. for (Index k=0; k<= N_+1; k++) {
  408. grad_f[y_index(0, 0, k)] = 0.;
  409. grad_f[y_index(N_+1,0, k)] = 0.;
  410. grad_f[y_index(0, N_+1,k)] = 0.;
  411. grad_f[y_index(N_+1,N_+1,k)] = 0.;
  412. }
  413. return true;
  414. }
  415. bool MittelmannBndryCntrlDiriBase3D_27::eval_g(Index n, const Number* x, bool new_x,
  416. Index m, Number* g)
  417. {
  418. // return the value of the constraints: g(x)
  419. // compute the discretized PDE for each interior grid point
  420. Index ig = 0;
  421. for (Index i=1; i<=N_; i++) {
  422. for (Index j=1; j<=N_; j++) {
  423. for (Index k=1; k<=N_; k++) {
  424. Number val;
  425. // Start with the discretized Laplacian operator
  426. val = 200.* x[y_index(i,j,k)]
  427. - 16.* (
  428. x[y_index(i+1,j ,k )] +
  429. x[y_index(i-1,j ,k )] +
  430. x[y_index(i ,j+1,k )] +
  431. x[y_index(i ,j-1,k )] +
  432. x[y_index(i ,j ,k+1)] +
  433. x[y_index(i ,j ,k-1)]
  434. )
  435. - 8. * (
  436. x[y_index(i+1,j+1,k )] +
  437. x[y_index(i+1,j-1,k )] +
  438. x[y_index(i-1,j+1,k )] +
  439. x[y_index(i-1,j-1,k )] +
  440. x[y_index(i ,j+1,k+1)] +
  441. x[y_index(i ,j+1,k-1)] +
  442. x[y_index(i ,j-1,k+1)] +
  443. x[y_index(i ,j-1,k-1)] +
  444. x[y_index(i+1,j ,k+1)] +
  445. x[y_index(i+1,j ,k-1)] +
  446. x[y_index(i-1,j ,k+1)] +
  447. x[y_index(i-1,j ,k-1)]
  448. )
  449. - 1. * (
  450. x[y_index(i+1,j+1,k+1)] +
  451. x[y_index(i+1,j-1,k+1)] +
  452. x[y_index(i+1,j+1,k-1)] +
  453. x[y_index(i+1,j-1,k-1)] +
  454. x[y_index(i-1,j+1,k+1)] +
  455. x[y_index(i-1,j-1,k+1)] +
  456. x[y_index(i-1,j+1,k-1)] +
  457. x[y_index(i-1,j-1,k-1)]
  458. );
  459. g[ig] = val;
  460. ig++;
  461. }
  462. }
  463. }
  464. DBG_ASSERT(ig==m);
  465. return true;
  466. }
  467. bool MittelmannBndryCntrlDiriBase3D_27::eval_jac_g(Index n, const Number* x, bool new_x,
  468. Index m, Index nele_jac, Index* iRow, Index *jCol,
  469. Number* values)
  470. {
  471. if (values == NULL) {
  472. // return the structure of the jacobian of the constraints
  473. Index ijac = 0;
  474. Index ig = 0;
  475. for (Index i=1; i<= N_; i++) {
  476. for (Index j=1; j<= N_; j++) {
  477. for (Index k=1; k<= N_; k++) {
  478. // y(i-1,j,k)
  479. iRow[ijac] = ig;
  480. jCol[ijac] = y_index(i-1,j,k);
  481. ijac++;
  482. // y(i,j,k)
  483. iRow[ijac] = ig;
  484. jCol[ijac] = y_index(i,j,k);
  485. ijac++;
  486. // y(i+1,j,k)
  487. iRow[ijac] = ig;
  488. jCol[ijac] = y_index(i+1,j,k);
  489. ijac++;
  490. // y(i-1,j-1,k)
  491. iRow[ijac] = ig;
  492. jCol[ijac] = y_index(i-1,j-1,k);
  493. ijac++;
  494. // y(i,j-1,k)
  495. iRow[ijac] = ig;
  496. jCol[ijac] = y_index(i,j-1,k);
  497. ijac++;
  498. // y(i+1,j-1,k)
  499. iRow[ijac] = ig;
  500. jCol[ijac] = y_index(i+1,j-1,k);
  501. ijac++;
  502. // y(i-1,j+1,k)
  503. iRow[ijac] = ig;
  504. jCol[ijac] = y_index(i-1,j+1,k);
  505. ijac++;
  506. // y(i,j+1,k)
  507. iRow[ijac] = ig;
  508. jCol[ijac] = y_index(i,j+1,k);
  509. ijac++;
  510. // y(i+1,j+1,k)
  511. iRow[ijac] = ig;
  512. jCol[ijac] = y_index(i+1,j+1,k);
  513. ijac++;
  514. // y(i-1,j,k-1)
  515. iRow[ijac] = ig;
  516. jCol[ijac] = y_index(i-1,j,k-1);
  517. ijac++;
  518. // y(i,j,k-1)
  519. iRow[ijac] = ig;
  520. jCol[ijac] = y_index(i,j,k-1);
  521. ijac++;
  522. // y(i+1,j,k-1)
  523. iRow[ijac] = ig;
  524. jCol[ijac] = y_index(i+1,j,k-1);
  525. ijac++;
  526. // y(i-1,j-1,k-1)
  527. iRow[ijac] = ig;
  528. jCol[ijac] = y_index(i-1,j-1,k-1);
  529. ijac++;
  530. // y(i,j-1,k-1)
  531. iRow[ijac] = ig;
  532. jCol[ijac] = y_index(i,j-1,k-1);
  533. ijac++;
  534. // y(i+1,j-1,k-1)
  535. iRow[ijac] = ig;
  536. jCol[ijac] = y_index(i+1,j-1,k-1);
  537. ijac++;
  538. // y(i-1,j+1,k-1)
  539. iRow[ijac] = ig;
  540. jCol[ijac] = y_index(i-1,j+1,k-1);
  541. ijac++;
  542. // y(i,j+1,k-1)
  543. iRow[ijac] = ig;
  544. jCol[ijac] = y_index(i,j+1,k-1);
  545. ijac++;
  546. // y(i+1,j+1,k-1)
  547. iRow[ijac] = ig;
  548. jCol[ijac] = y_index(i+1,j+1,k-1);
  549. ijac++;
  550. // y(i-1,j,k+1)
  551. iRow[ijac] = ig;
  552. jCol[ijac] = y_index(i-1,j,k+1);
  553. ijac++;
  554. // y(i,j,k+1)
  555. iRow[ijac] = ig;
  556. jCol[ijac] = y_index(i,j,k+1);
  557. ijac++;
  558. // y(i+1,j,k+1)
  559. iRow[ijac] = ig;
  560. jCol[ijac] = y_index(i+1,j,k+1);
  561. ijac++;
  562. // y(i-1,j-1,k+1)
  563. iRow[ijac] = ig;
  564. jCol[ijac] = y_index(i-1,j-1,k+1);
  565. ijac++;
  566. // y(i,j-1,k+1)
  567. iRow[ijac] = ig;
  568. jCol[ijac] = y_index(i,j-1,k+1);
  569. ijac++;
  570. // y(i+1,j-1,k+1)
  571. iRow[ijac] = ig;
  572. jCol[ijac] = y_index(i+1,j-1,k+1);
  573. ijac++;
  574. // y(i-1,j+1,k+1)
  575. iRow[ijac] = ig;
  576. jCol[ijac] = y_index(i-1,j+1,k+1);
  577. ijac++;
  578. // y(i,j+1,k+1)
  579. iRow[ijac] = ig;
  580. jCol[ijac] = y_index(i,j+1,k+1);
  581. ijac++;
  582. // y(i+1,j+1,k+1)
  583. iRow[ijac] = ig;
  584. jCol[ijac] = y_index(i+1,j+1,k+1);
  585. ijac++;
  586. ig++;
  587. }
  588. }
  589. }
  590. DBG_ASSERT(ijac==nele_jac);
  591. }
  592. else {
  593. // return the values of the jacobian of the constraints
  594. Index ijac = 0;
  595. for (Index i=1; i<= N_; i++) {
  596. for (Index j=1; j<= N_; j++) {
  597. for (Index k=1; k<= N_; k++) {
  598. // y(i-1,j,k)
  599. values[ijac] = -16.;
  600. ijac++;
  601. // y(i,j,k)
  602. values[ijac] = 200.;
  603. ijac++;
  604. // y(i+1,j,k)
  605. values[ijac] = -16.;
  606. ijac++;
  607. // y(i-1,j-1,k)
  608. values[ijac] = -8.;
  609. ijac++;
  610. // y(i,j-1,k)
  611. values[ijac] = -16.;
  612. ijac++;
  613. // y(i+1,j-1,k)
  614. values[ijac] = -8.;
  615. ijac++;
  616. // y(i-1,j+1,k)
  617. values[ijac] = -8.;
  618. ijac++;
  619. // y(i,j+1,k)
  620. values[ijac] = -16.;
  621. ijac++;
  622. // y(i+1,j+1,k)
  623. values[ijac] = -8.;
  624. ijac++;
  625. // y(i-1,j,k-1)
  626. values[ijac] = -8.;
  627. ijac++;
  628. // y(i,j,k-1)
  629. values[ijac] = -16.;
  630. ijac++;
  631. // y(i+1,j,k-1)
  632. values[ijac] = -8.;
  633. ijac++;
  634. // y(i-1,j-1,k-1)
  635. values[ijac] = -1.;
  636. ijac++;
  637. // y(i,j-1,k-1)
  638. values[ijac] = -8.;
  639. ijac++;
  640. // y(i+1,j-1,k-1)
  641. values[ijac] = -1.;
  642. ijac++;
  643. // y(i-1,j+1,k-1)
  644. values[ijac] = -1.;
  645. ijac++;
  646. // y(i,j+1,k-1)
  647. values[ijac] = -8.;
  648. ijac++;
  649. // y(i+1,j+1,k-1)
  650. values[ijac] = -1.;
  651. ijac++;
  652. // y(i-1,j,k+1)
  653. values[ijac] = -8.;
  654. ijac++;
  655. // y(i,j,k+1)
  656. values[ijac] = -16.;
  657. ijac++;
  658. // y(i+1,j,k+1)
  659. values[ijac] = -8.;
  660. ijac++;
  661. // y(i-1,j-1,k+1)
  662. values[ijac] = -1.;
  663. ijac++;
  664. // y(i,j-1,k+1)
  665. values[ijac] = -8.;
  666. ijac++;
  667. // y(i+1,j-1,k+1)
  668. values[ijac] = -1.;
  669. ijac++;
  670. // y(i-1,j+1,k+1)
  671. values[ijac] = -1.;
  672. ijac++;
  673. // y(i,j+1,k+1)
  674. values[ijac] = -8.;
  675. ijac++;
  676. // y(i+1,j+1,k+1)
  677. values[ijac] = -1.;
  678. ijac++;
  679. }
  680. }
  681. }
  682. DBG_ASSERT(ijac==nele_jac);
  683. }
  684. return true;
  685. }
  686. bool
  687. MittelmannBndryCntrlDiriBase3D_27::eval_h(Index n, const Number* x, bool new_x,
  688. Number obj_factor, Index m,
  689. const Number* lambda,
  690. bool new_lambda, Index nele_hess, Index* iRow,
  691. Index* jCol, Number* values)
  692. {
  693. if (values == NULL) {
  694. // return the structure. This is a symmetric matrix, fill the lower left
  695. // triangle only.
  696. Index ihes=0;
  697. // First the diagonal entries for y(i,j)
  698. for (Index i=1; i<= N_; i++) {
  699. for (Index j=1; j<= N_; j++) {
  700. for (Index k=1; k<= N_; k++) {
  701. iRow[ihes] = y_index(i,j,k);
  702. jCol[ihes] = y_index(i,j,k);
  703. ihes++;
  704. }
  705. }
  706. }
  707. if (alpha_>0.) {
  708. // Now the diagonal entries for u at the boundary
  709. for (Index i=1; i<=N_; i++) {
  710. for (Index j=1; j<=N_; j++) {
  711. Index iu = y_index(i,j,0);
  712. iRow[ihes] = iu;
  713. jCol[ihes] = iu;
  714. ihes++;
  715. }
  716. }
  717. for (Index i=1; i<=N_; i++) {
  718. for (Index j=1; j<=N_; j++) {
  719. Index iu = y_index(i,j,N_+1);
  720. iRow[ihes] = iu;
  721. jCol[ihes] = iu;
  722. ihes++;
  723. }
  724. }
  725. for (Index k=1; k<=N_; k++) {
  726. for (Index j=1; j<=N_; j++) {
  727. Index iu = y_index(0,j,k);
  728. iRow[ihes] = iu;
  729. jCol[ihes] = iu;
  730. ihes++;
  731. }
  732. }
  733. for (Index k=1; k<=N_; k++) {
  734. for (Index j=1; j<=N_; j++) {
  735. Index iu = y_index(N_+1,j,k);
  736. iRow[ihes] = iu;
  737. jCol[ihes] = iu;
  738. ihes++;
  739. }
  740. }
  741. for (Index i=1; i<=N_; i++) {
  742. for (Index k=1; k<=N_; k++) {
  743. Index iu = y_index(i,0,k);
  744. iRow[ihes] = iu;
  745. jCol[ihes] = iu;
  746. ihes++;
  747. }
  748. }
  749. for (Index i=1; i<=N_; i++) {
  750. for (Index k=1; k<=N_; k++) {
  751. Index iu = y_index(i,N_+1,k);
  752. iRow[ihes] = iu;
  753. jCol[ihes] = iu;
  754. ihes++;
  755. }
  756. }
  757. }
  758. DBG_ASSERT(ihes==nele_hess);
  759. }
  760. else {
  761. // return the values
  762. Index ihes=0;
  763. // First the diagonal entries for y(i,j)
  764. for (Index i=1; i<= N_; i++) {
  765. for (Index j=1; j<= N_; j++) {
  766. for (Index k=1; k<= N_; k++) {
  767. // Contribution from the objective function
  768. Index iy = y_index(i,j,k);
  769. values[ihes] = obj_factor*hhh_*PenObj_2(x[iy] - y_d_[iy]);
  770. ihes++;
  771. }
  772. }
  773. }
  774. // Now the diagonal entries for u(i,j)
  775. if (alpha_>0.) {
  776. // Now the diagonal entries for u at the boundary
  777. for (Index i=1; i<=N_; i++) {
  778. for (Index j=1; j<=N_; j++) {
  779. values[ihes] = obj_factor*hh_*alpha_;
  780. ihes++;
  781. }
  782. }
  783. for (Index i=1; i<=N_; i++) {
  784. for (Index j=1; j<=N_; j++) {
  785. values[ihes] = obj_factor*hh_*alpha_;
  786. ihes++;
  787. }
  788. }
  789. for (Index i=1; i<=N_; i++) {
  790. for (Index j=1; j<=N_; j++) {
  791. values[ihes] = obj_factor*hh_*alpha_;
  792. ihes++;
  793. }
  794. }
  795. for (Index i=1; i<=N_; i++) {
  796. for (Index j=1; j<=N_; j++) {
  797. values[ihes] = obj_factor*hh_*alpha_;
  798. ihes++;
  799. }
  800. }
  801. for (Index i=1; i<=N_; i++) {
  802. for (Index j=1; j<=N_; j++) {
  803. values[ihes] = obj_factor*hh_*alpha_;
  804. ihes++;
  805. }
  806. }
  807. for (Index i=1; i<=N_; i++) {
  808. for (Index j=1; j<=N_; j++) {
  809. values[ihes] = obj_factor*hh_*alpha_;
  810. ihes++;
  811. }
  812. }
  813. }
  814. }
  815. return true;
  816. }
  817. void
  818. MittelmannBndryCntrlDiriBase3D_27::finalize_solution(SolverReturn status,
  819. Index n, const Number* x, const Number* z_L, const Number* z_U,
  820. Index m, const Number* g, const Number* lambda, Number obj_value,
  821. const IpoptData* ip_data,
  822. IpoptCalculatedQuantities* ip_cq)
  823. {
  824. /*
  825. FILE* fp = fopen("solution.txt", "w+");
  826. for (Index i=0; i<=N_+1; i++) {
  827. for (Index j=0; j<=N_+1; j++) {
  828. fprintf(fp, "y[%6d,%6d] = %15.8e\n", i, j, x[y_index(i,j)]);
  829. }
  830. }
  831. fclose(fp);
  832. */
  833. }