CONOPT
Loading...
Searching...
No Matches
pinadd2.f90
Go to the documentation of this file.
1!> @file pinadd2.f90
2!! @ingroup FORT1THREAD_EXAMPLES
3!!
4!!
5!! This is a CONOPT implementation of the Pindyck model from the
6!! GAMS model library. The implementation is similar to the one
7!! in pindyck, but this time we first solve the model for 16
8!! periods and then we gradually increase the number of periods
9!! one at a time up to 20.
10!!
11!!
12!! For more information about the individual callbacks, please have a look at the source code.
13
14#if defined(_WIN32) && !defined(_WIN64)
15#define dec_directives_win32
16#endif
17
18Module pinadd2data
19 integer :: T
20 integer, Parameter :: Tmin = 16, tmax = 20
21 integer, Parameter :: vpp = 7 ! Variables per period
22 integer, Parameter :: epp = 6 ! Equations per period
23 Integer, Parameter :: hpp = 5 ! Hessian elements per period -- see in 2DLagr* routines
24 real*8, Dimension(Tmax*Vpp) :: xkeep ! Store previous solutions
25 Integer, Dimension(Tmax*Vpp) :: xstas ! Store previous status
26 Integer, Dimension(Tmax*Epp) :: estat ! for variables and equations
27End Module pinadd2data
29!> Main program. A simple setup and call of CONOPT
30!!
31Program pinadd2
32 Use proginfo
34 Use pinadd2data
35 Implicit none
36!
37! Declare the user callback routines as Integer, External:
38!
39 Integer, External :: pin_readmatrix ! Mandatory Matrix definition routine defined below
40 Integer, External :: pin_fdeval ! Function and Derivative evaluation routine
41 ! needed a nonlinear model.
42 Integer, External :: std_status ! Standard callback for displaying solution status
43 Integer, External :: pin_solution ! Specialized callback for displaying solution values
44 Integer, External :: std_message ! Standard callback for managing messages
45 Integer, External :: std_errmsg ! Standard callback for managing error messages
46 Integer, External :: pin_2dlagrstr ! Hessian structure evaluation routine
47 Integer, External :: pin_2dlagrval ! Hessian value evaluation routine
48#ifdef dec_directives_win32
49!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_ReadMatrix
50!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_FDEval
51!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Status
52!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_Solution
53!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Message
54!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_ErrMsg
55!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_2DLagrStr
56!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_2DLagrVal
57#endif
58!
59! Control vector
60!
61 INTEGER, Dimension(:), Pointer :: cntvect
62 INTEGER :: coi_error
63
64 call startup
65!
66! Create and initialize a Control Vector
67!
68 coi_error = coi_create( cntvect )
69!
70! Define the number of time periods, T.
71!
72 t = tmin
73!
74! Tell CONOPT about the size of the model by populating the Control Vector:
75!
76! Number of variables (excl. slacks): Vpp per period
77!
78 coi_error = max( coi_error, coidef_numvar( cntvect, vpp * t ) )
79!
80! Number of equations: 1 objective + Epp per period
81!
82 coi_error = max( coi_error, coidef_numcon( cntvect, 1 + epp * t ) )
83!
84! Number of nonzeros in the Jacobian. See the counting in ReadMatrix below:
85! For each period there is 1 in the objective, 16 for unlagged
86! variables and 4 for lagged variables.
87!
88 coi_error = max( coi_error, coidef_numnz( cntvect, 17 * t + 4 * (t-1) ) )
89!
90! Number of nonlinear nonzeros. 5 unlagged for each period.
91!
92 coi_error = max( coi_error, coidef_numnlnz( cntvect, 5 * t ) )
93!
94! Number of nonzeros in the Hessian. 5 for each period.
95!
96 coi_error = max( coi_error, coidef_numhess( cntvect, hpp * t ) )
97!
98! Direction: +1 = maximization.
99!
100 coi_error = max( coi_error, coidef_optdir( cntvect, 1 ) )
101!
102! Objective: Constraint no 1
103!
104 coi_error = max( coi_error, coidef_objcon( cntvect, 1 ) )
105!
106! Turn Hessian debugging on in the initial point
107!
108 coi_error = max( coi_error, coidef_debug2d( cntvect, -1 ) )
109!
110! Options file = test.opt
111!
112 coi_error = max( coi_error, coidef_optfile( cntvect, 'test.opt' ) )
113!
114! Tell CONOPT about the callback routines:
115!
116 coi_error = max( coi_error, coidef_readmatrix( cntvect, pin_readmatrix ) )
117 coi_error = max( coi_error, coidef_fdeval( cntvect, pin_fdeval ) )
118 coi_error = max( coi_error, coidef_status( cntvect, std_status ) )
119 coi_error = max( coi_error, coidef_solution( cntvect, pin_solution ) )
120 coi_error = max( coi_error, coidef_message( cntvect, std_message ) )
121 coi_error = max( coi_error, coidef_errmsg( cntvect, std_errmsg ) )
122 coi_error = max( coi_error, coidef_2dlagrstr( cntvect, pin_2dlagrstr ) )
123 coi_error = max( coi_error, coidef_2dlagrval( cntvect, pin_2dlagrval ) )
124
125#if defined(CONOPT_LICENSE_INT_1) && defined(CONOPT_LICENSE_INT_2) && defined(CONOPT_LICENSE_INT_3) && defined(CONOPT_LICENSE_TEXT)
126 coi_error = max( coi_error, coidef_license( cntvect, conopt_license_int_1, conopt_license_int_2, conopt_license_int_3, conopt_license_text) )
127#endif
128
129 If ( coi_error .ne. 0 ) THEN
130 write(*,*)
131 write(*,*) '**** Fatal Error while loading CONOPT Callback routines.'
132 write(*,*)
133 call flog( "Skipping First Solve due to setup errors", 1 )
134 ENDIF
135!
136! Start CONOPT:
137!
138 coi_error = coi_solve( cntvect )
139 If ( coi_error .ne. 0 ) THEN
140 write(*,*)
141 write(*,*) '**** Fatal Error while Solving first model.'
142 write(*,*)
143 call flog( "Errors encountered during first Solve.", 1 )
144 elseif ( stacalls == 0 .or. solcalls == 0 ) then
145 call flog( "Status or Solution routine was not called during first Solve", 1 )
146 else if ( mstat /= 2 .or. sstat /= 1 ) then
147 call flog( "Incorrect Model or Solver Status during first solve", 1 )
148 ENDIF
149!
150! Now increase the time horizon gradually up to 20.
151! All sizes that depend on T must be registered again.
152!
153 Do t = tmin+1, tmax
154 coi_error = max( coi_error, coidef_numvar( cntvect, 7 * t ) )
155 coi_error = max( coi_error, coidef_numcon( cntvect, 1 + 6 * t ) )
156 coi_error = max( coi_error, coidef_numnz( cntvect, 17 * t + 4 * (t-1) ) )
157 coi_error = max( coi_error, coidef_numnlnz( cntvect, 5 * t ) )
158 coi_error = max( coi_error, coidef_numhess( cntvect, hpp * t ) )
159!
160! This time we have status information copied from a previous solve, i.e.
161! IniStat = 2
162!
163 coi_error = max( coi_error, coidef_inistat( cntvect, 2 ) )
164!
165! Turn Hessian debugging off again
166!
167 coi_error = max( coi_error, coidef_debug2d( cntvect, 0 ) )
168 If ( coi_error .ne. 0 ) THEN
169 write(*,*)
170 write(*,*) '**** Fatal Error while revising CONOPT Sizes.'
171 write(*,*)
172 call flog( "Skipping Later Solve due to setup errors", 1 )
173 ENDIF
174 coi_error = coi_solve( cntvect )
175 If ( coi_error .ne. 0 ) THEN
176 write(*,*)
177 write(*,*) '**** Fatal Error while Solving for T=',t
178 write(*,*)
179 call flog( "Errors encountered during later Solve.", 1 )
180 elseif ( stacalls == 0 .or. solcalls == 0 ) then
181 call flog( "Status or Solution routine was not called during later Solve", 1 )
182 else if ( mstat /= 2 .or. sstat /= 1 ) then
183 call flog( "Incorrect Model or Solver Status during later solve", 1 )
184 ENDIF
185 Enddo
186 write(*,*)
187 write(*,*) 'End of Pinadd2 Model. Return code=',coi_error
188
189 if ( coi_free(cntvect) /= 0 ) call flog( "Error while freeing control vector",1)
190
191 call flog( "Successful Solve", 0 )
192!
193! Free solution memory
194!
196
197end Program pinadd2
198!
199! =====================================================================
200! Define information about the model structure
201!
202
203!> Define information about the model
204!!
205!! @include{doc} readMatrix_params.dox
206Integer Function pin_readmatrix( lower, curr, upper, vsta, type, rhs, esta, &
207 colsta, rowno, value, nlflag, n, m, nz, usrmem )
208#ifdef dec_directives_win32
209!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_ReadMatrix
210#endif
211 Use pinadd2data
212 implicit none
213 integer, intent (in) :: n ! number of variables
214 integer, intent (in) :: m ! number of constraints
215 integer, intent (in) :: nz ! number of nonzeros
216 real*8, intent (in out), dimension(n) :: lower ! vector of lower bounds
217 real*8, intent (in out), dimension(n) :: curr ! vector of initial values
218 real*8, intent (in out), dimension(n) :: upper ! vector of upper bounds
219 integer, intent (in out), dimension(n) :: vsta ! vector of initial variable status
220 ! Defined during restarts
221 integer, intent (out), dimension(m) :: type ! vector of equation types
222 integer, intent (in out), dimension(m) :: esta ! vector of initial equation status
223 ! Defined during restarts
224 real*8, intent (in out), dimension(m) :: rhs ! vector of right hand sides
225 integer, intent (in out), dimension(n+1) :: colsta ! vector with start of column indices
226 integer, intent (out), dimension(nz) :: rowno ! vector of row numbers
227 integer, intent (in out), dimension(nz) :: nlflag ! vector of nonlinearity flags
228 real*8, intent (in out), dimension(nz) :: value ! vector of matrix values
229 real*8 usrmem(*) ! optional user memory
230
231 Integer :: it, is, i, icol, iz, iold
232!
233! Define the information for the columns.
234!
235! We should not supply status information, vsta.
236!
237! We order the variables as follows:
238! td, cs, s, d, r, p, and rev. All variables for period 1 appears
239! first followed by all variables for period 2 etc.
240!
241! td, cs, s, and d have lower bounds of 0, r and p have lower
242! bounds of 1, and rev has no lower bound.
243! All have infinite upper bounds (default).
244! The initial value of td is 18, s is 7, cs is 7*t, d is td-s,
245! p is 14, and r is r(t-1)-d. No initial value for rev.
246!
247 do it = 1, t
248 is = vpp*(it-1)
249 lower(is+1) = 0.d0
250 lower(is+2) = 0.d0
251 lower(is+3) = 0.d0
252 lower(is+4) = 0.d0
253 lower(is+5) = 1.d0
254 lower(is+6) = 1.d0
255 curr(is+1) = 18.d0
256 curr(is+2) = 7.d0*it
257 curr(is+3) = 7.d0
258 curr(is+4) = curr(is+1) - curr(is+3)
259 if ( it .gt. 1 ) then
260 curr(is+5) = curr(is+5-vpp) - curr(is+4)
261 else
262 curr(is+5) = 500.d0 - curr(is+4)
263 endif
264 curr(is+6) = 14.d0
265 enddo
266 If ( t > tmin ) Then
267!
268! This is a restart: Use the initial values from last solve for
269! the variables in the first periods and extrapolate the last
270! period using a linear extrapolation between the last two
271!
272 iold = vpp*(t-1)
273 curr(1:iold) = xkeep(1:iold)
274 do i = 1, vpp
275 curr(iold+i) = curr(iold+i-vpp) + (curr(iold+i-vpp)-curr(iold+i-2*vpp))
276 enddo
277!
278! The variables from the last solve are given the old status and
279! the variables in the new period are given those in the last
280! pariod. Similarly with the Equation status:
281!
282 vsta(1:iold) = xstas(1:iold)
283 do i = 1, vpp
284 vsta(iold+i) = xstas(iold+i-vpp)
285 enddo
286 iold = 6*(t-1)+1
287 esta(1:iold) = estat(1:iold)
288 do i = 1, epp
289 esta(iold+i) = estat(iold+i-epp)
290 enddo
291 endif
292!
293! Define the information for the rows
294!
295! We order the constraints as follows: The objective is first,
296! followed by tddef, sdef, csdef, ddef, rdef, and revdef for
297! the first period, the same for the second period, etc.
298!
299! The objective is a nonbinding constraint:
300!
301 type(1) = 3
302!
303! All others are equalities:
304!
305 do i = 2, m
306 type(i) = 0
307 enddo
308!
309! Right hand sides: In all periods except the first, only tddef
310! has a nonzero right hand side of 1+2.3*1.015**(t-1).
311! In the initial period there are contributions from lagged
312! variables in the constraints that have lagged variables.
313!
314 do it = 1, t
315 is = 1 + 6*(it-1)
316 rhs(is+1) = 1.d0+2.3d0*1.015d0**(it-1)
317 enddo
318!
319! tddef: + 0.87*td(0)
320!
321 rhs(2) = rhs(2) + 0.87d0*18.d0
322!
323! sdef: +0.75*s(0)
324!
325 rhs(3) = 0.75d0*6.5d0
326!
327! csdef: +1*cs(0)
328!
329 rhs(4) = 0.d0
330!
331! rdef: +1*r(0)
332!
333 rhs(6) = 500.d0
334!
335! Define the structure and content of the Jacobian:
336! To help define the Jacobian pattern and values it can be useful to
337! make a picture of the Jacobian. We describe the variables for one
338! period and the constraints they are part of:
339!
340! td cs s d r p rev
341! Obj (1+r)**(1-t)
342! Period t:
343! tddef 1.0 0.13
344! sdef NL 1.0 NL
345! csdef 1.0 -1.0
346! ddef -1.0 1.0 1.0
347! rdef 1.0 1.0
348! revdef NL NL NL 1.0
349! Period t+1:
350! tddef -0.87
351! sdef -0.75
352! csdef -1.0
353! ddef
354! rdef -1.0
355! revdef
356!
357! The Jacobian has to be sorted column-wise so we will just define
358! the elements column by column according to the table above:
359!
360 iz = 1
361 icol = 1
362 do it = 1, t
363!
364! is points to the position before the first equation for the period
365!
366 is = 1 + 6*(it-1)
367!
368! Column td:
369!
370 colsta(icol) = iz
371 icol = icol + 1
372 rowno(iz) = is+1
373 value(iz) = +1.d0
374 nlflag(iz) = 0
375 iz = iz + 1
376 rowno(iz) = is+4
377 value(iz) = -1.d0
378 nlflag(iz) = 0
379 iz = iz + 1
380 if ( it .lt. t ) then
381 rowno(iz) = is+7
382 value(iz) = -0.87d0
383 nlflag(iz) = 0
384 iz = iz + 1
385 endif
386!
387! Column cs
388!
389 colsta(icol) = iz
390 icol = icol + 1
391 rowno(iz) = is+2
392 nlflag(iz) = 1
393 iz = iz + 1
394 rowno(iz) = is+3
395 value(iz) = +1.d0
396 nlflag(iz) = 0
397 iz = iz + 1
398 if ( it .lt. t ) then
399 rowno(iz) = is+9
400 value(iz) = -1.d0
401 nlflag(iz) = 0
402 iz = iz + 1
403 endif
404!
405! Column s
406!
407 colsta(icol) = iz
408 icol = icol + 1
409 rowno(iz) = is+2
410 value(iz) = +1.d0
411 nlflag(iz) = 0
412 iz = iz + 1
413 rowno(iz) = is+3
414 value(iz) = -1.d0
415 nlflag(iz) = 0
416 iz = iz + 1
417 rowno(iz) = is+4
418 value(iz) = +1.d0
419 nlflag(iz) = 0
420 iz = iz + 1
421 if ( it .lt. t ) then
422 rowno(iz) = is+8
423 value(iz) = -0.75d0
424 nlflag(iz) = 0
425 iz = iz + 1
426 endif
427!
428! Column d:
429!
430 colsta(icol) = iz
431 icol = icol + 1
432 rowno(iz) = is+4
433 value(iz) = +1.d0
434 nlflag(iz) = 0
435 iz = iz + 1
436 rowno(iz) = is+5
437 value(iz) = +1.d0
438 nlflag(iz) = 0
439 iz = iz + 1
440 rowno(iz) = is+6
441 nlflag(iz) = 1
442 iz = iz + 1
443!
444! Column r:
445!
446 colsta(icol) = iz
447 icol = icol + 1
448 rowno(iz) = is+5
449 value(iz) = +1.d0
450 nlflag(iz) = 0
451 iz = iz + 1
452 rowno(iz) = is+6
453 nlflag(iz) = 1
454 iz = iz + 1
455 if ( it .lt. t ) then
456 rowno(iz) = is+11
457 value(iz) = -1.d0
458 nlflag(iz) = 0
459 iz = iz + 1
460 endif
461!
462! Column p:
463!
464 colsta(icol) = iz
465 icol = icol + 1
466 rowno(iz) = is+1
467 value(iz) = +0.13d0
468 nlflag(iz) = 0
469 iz = iz + 1
470 rowno(iz) = is+2
471 nlflag(iz) = 1
472 iz = iz + 1
473 rowno(iz) = is+6
474 nlflag(iz) = 1
475 iz = iz + 1
476!
477! Column rev:
478!
479 colsta(icol) = iz
480 icol = icol + 1
481 rowno(iz) = +1
482 value(iz) = 1.05d0**(1-it)
483 nlflag(iz) = 0
484 iz = iz + 1
485 rowno(iz) = is+6
486 value(iz) = 1.d0
487 nlflag(iz) = 0
488 iz = iz + 1
489 enddo
490 colsta(icol) = iz
491
493
494end Function pin_readmatrix
495!
496! =====================================================================
497! Compute nonlinear terms and non-constant Jacobian elements
498!
499
500!> Compute nonlinear terms and non-constant Jacobian elements
501!!
502!! @include{doc} fdeval_params.dox
503Integer Function pin_fdeval( x, g, jac, rowno, jcnm, mode, ignerr, errcnt, &
504 n, nz, thread, usrmem )
505#ifdef dec_directives_win32
506!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_FDEval
507#endif
508 Use pinadd2data
509 implicit none
510 integer, intent (in) :: n ! number of variables
511 integer, intent (in) :: rowno ! number of the row to be evaluated
512 integer, intent (in) :: nz ! number of nonzeros in this row
513 real*8, intent (in), dimension(n) :: x ! vector of current solution values
514 real*8, intent (in out) :: g ! constraint value
515 real*8, intent (in out), dimension(n) :: jac ! vector of derivatives for current constraint
516 integer, intent (in), dimension(nz) :: jcnm ! list of variables that appear nonlinearly
517 ! in this row. Ffor information only.
518 integer, intent (in) :: mode ! evaluation mode: 1 = function value
519 ! 2 = derivatives, 3 = both
520 integer, intent (in) :: ignerr ! if 1 then errors can be ignored as long
521 ! as errcnt is incremented
522 integer, intent (in out) :: errcnt ! error counter to be incremented in case
523 ! of function evaluation errors.
524 integer, intent (in) :: thread
525 real*8 usrmem(*) ! optional user memory
526
527 integer :: it, is
528 real*8 :: h1, h2
529!
530! Compute the number of the period
531!
532 it = (rowno+4) / epp
533 is = vpp*(it-1)
534 if ( rowno == (it-1)*epp+3 ) then
535!
536! sdef equation. Nonlinear term = -(1.1+0.1*p)*1.02**(-cs/7)
537!
538 h1 = (1.1d0+0.1d0*x(is+6))
539 h2 = 1.02d0**(-x(is+2)/7.d0)
540 if ( mode == 1 .or. mode == 3 ) then
541 g = -h1*h2
542 endif
543 if ( mode == 2 .or. mode == 3 ) then
544 jac(is+2) = h1*h2*log(1.02d0)/7.d0
545 jac(is+6) = -h2*0.1d0
546 endif
547 elseif ( rowno == (it-1)*epp+7 ) then
548!
549! revdef equation. Nonlinear term = -d*(p-250/r)
550!
551 if ( mode == 1 .or. mode == 3 ) then
552 g = -x(is+4)*(x(is+6)-250.d0/x(is+5))
553 endif
554 if ( mode == 2 .or. mode == 3 ) then
555 jac(is+4) = -(x(is+6)-250.d0/x(is+5))
556 jac(is+5) = -x(is+4)*250d0/x(is+5)**2
557 jac(is+6) = -x(is+4)
558 endif
559 else
560!
561! Error - this equation is not nonlinear
562!
563 write(*,*)
564 write(*,*) 'Error. FDEval called with rowno=',rowno
565 write(*,*)
566 pin_fdeval = 1
567 Return
568 endif
569 pin_fdeval = 0
570
571end Function pin_fdeval
572
573Integer Function pin_solution( XVAL, XMAR, XBAS, XSTA, YVAL, YMAR, YBAS, YSTA, N, M, USRMEM )
574#ifdef dec_directives_win32
575!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_Solution
576#endif
577
578 Use pinadd2data
579 Use proginfo
580 IMPLICIT NONE
581 INTEGER, Intent(IN) :: n, m
582 INTEGER, Intent(IN), Dimension(N) :: xbas, xsta
583 INTEGER, Intent(IN), Dimension(M) :: ybas, ysta
584 real*8, Intent(IN), Dimension(N) :: xval, xmar
585 real*8, Intent(IN), Dimension(M) :: yval, ymar
586 real*8, Intent(IN OUT) :: usrmem(*)
587 character*6, parameter, dimension(7) :: vname = (/'td ','cs ','s ','d ','r ','p ','rev '/)
588 character*6, parameter, dimension(6) :: ename = (/'tddef ','sdef ','csdef ','ddef ','rdef ','revdef'/)
589
590 INTEGER :: i, it, i1
591 CHARACTER*5, Parameter, Dimension(4) :: stat = (/ 'Lower','Upper','Basic','Super' /)
592
593 solcalls = solcalls + 1
594 If ( t < tmax ) Then
595 Write(*,"(A,i3)") 'Saving primal solution and status information for T =',t
596 xkeep(1:n) = xval(1:n)
597 xstas(1:n) = xbas(1:n)
598 estat(1:m) = ybas(1:m)
599 pin_solution = 0
600 Return
601 Endif
602
603 WRITE(10,"(/' Variable Solution value Reduced cost B-stat'/)")
604 i = 0
605 do it = 1, t
606 DO i1 = 1, vpp
607 i = i + 1
608 WRITE(10,"(1X,A6,i2,1p,E20.6,E16.6,4X,A5 )") vname(i1), it, xval(i), xmar(i), stat(1+xbas(i))
609 ENDDO
610 enddo
611
612 WRITE(10,"(/' Constrnt Activity level Marginal cost B-stat'/)")
613 i = 1
614 WRITE(10,"(1x,'Objective',1P,E19.6,E16.6,4X,A5 )") yval(i), ymar(i), stat(1+ybas(i))
615 do it = 1, t
616 do i1 = 1, epp
617 i = i + 1
618 WRITE(10,"(1x,A6,i2,1P,E20.6,E16.6,4X,A5 )") ename(i1),it, yval(i), ymar(i), stat(1+ybas(i))
619 enddo
620 ENDDO
621
622 pin_solution = 0
623
624END Function pin_solution
625
626
627!> Specify the structure of the Lagrangian of the Hessian
628!!
629!! @include{doc} 2DLagrStr_params.dox
630Integer Function pin_2dlagrstr( HSRW, HSCL, NODRV, N, M, NHESS, UsrMem )
631#ifdef dec_directives_win32
632!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_2DLagrStr
633#endif
634 USE pinadd2data
635 Implicit None
636
637 Integer, Intent (IN) :: n, m, nhess
638 Integer, Intent (IN OUT) :: nodrv
639 Integer, Dimension(NHess), Intent (Out) :: hsrw, hscl
640 real*8, Intent(IN OUT) :: usrmem(*)
641
642 Integer :: it, is, ic
643!
644! There are two nonlinear constraints, Sdef and RevDef and they have
645! the following Hessians (for each time period):
646!
647! Revdef equation. Nonlinear term = -d*(p-250/r)
648! Hessian (diagonal and lower triangle): A total of 3 nonzero elements per period
649! 4 5 6
650! d r p
651! 4 : d
652! 5 : r -250/r**2 500*d/r**3
653! 6 : p -1
654!
655! Sdef: Nonlinear term = -(1.1+0.1p)*1.02**(-cs/7)
656! Hessian (diagonal and lower triangle): A total of 2 nonzero elements per period
657! 2 6
658! cs p
659! 2 : cs -(1.1+0.1p)*1.02**(-cs/7)*(log(1.02)/7)**2
660! 6 : p 0.1*1.02**(-cs/7)*(log(1.02)72)
661!
662! The two Hessian matrices do not overlap so the total number of nonzeros is
663! 5 per period. The structure using numerical indices for rows and columns and
664! running indices for the Hessian element is:
665!
666! 2 4 5 6
667! 2 1
668! 4
669! 5 3 5
670! 6 2 4
671!
672! and the same with names of variables and contributing equations
673! cs d r p
674! cs sdef
675! d
676! r revdef revdef
677! p sdef revdef
678!
679!
680! Define structure of Hessian
681!
682 if ( n /= vpp*t ) then
683 write(*,*) 'Struct: Number of variables should be=',vpp*t,' but CONOPT uses',n
684 write(*,*) 'Number of periods=',t
685 pin_2dlagrstr = 1; Return
686 stop
687 endif
688 if ( m /= epp*t+1 ) then
689 write(*,*) 'Struct: Number of equations should be=',epp*t+1,' but CONOPT uses',m
690 write(*,*) 'Number of periods=',t
691 pin_2dlagrstr = 1; Return
692 endif
693 Do it = 1, t
694 is = hpp*(it-1)
695 ic = vpp*(it-1)
696 hscl(is+1) = ic+2; hsrw(is+1) = ic+2
697 hscl(is+2) = ic+2; hsrw(is+2) = ic+6
698 hscl(is+3) = ic+4; hsrw(is+3) = ic+5
699 hscl(is+4) = ic+4; hsrw(is+4) = ic+6
700 hscl(is+5) = ic+5; hsrw(is+5) = ic+5
701 Enddo
702
703 pin_2dlagrstr = 0
704
705End Function pin_2dlagrstr
706
707
708!> Compute the Lagrangian of the Hessian
709!!
710!! @include{doc} 2DLagrVal_params.dox
711Integer Function pin_2dlagrval( X, U, HSRW, HSCL, HSVL, NODRV, N, M, NHESS, UsrMem )
712#ifdef dec_directives_win32
713!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Pin_2DLagrVal
714#endif
715 USE pinadd2data
716 Implicit None
717
718 Integer, Intent (IN) :: n, m, nhess
719 Integer, Intent (IN OUT) :: nodrv
720 real*8, Dimension(N), Intent (IN) :: x
721 real*8, Dimension(M), Intent (IN) :: u
722 Integer, Dimension(Nhess), Intent (IN) :: hsrw, hscl
723 real*8, Dimension(NHess), Intent (Out) :: hsvl
724 real*8, Intent(IN OUT) :: usrmem(*)
725
726 Integer :: it, is, ic, ie
727 real*8 :: cs, d, r, p
728 real*8 :: h1, h2
729!
730! There are two nonlinear constraints, Sdef and RevDef and they have
731! the following Hessians (for each time period):
732!
733! Revdef equation. Nonlinear term = -d*(p-250/r)
734! Hessian (diagonal and lower triangle): A total of 3 nonzero elements per period
735! 4 5 6
736! d r p
737! 4 : d
738! 5 : r -250/r**2 500*d/r**3
739! 6 : p -1
740!
741! Sdef: Nonlinear term = -(1.1+0.1p)*1.02**(-cs/7)
742! Hessian (diagonal and lower triangle): A total of 2 nonzero elements per period
743! 2 6
744! cs p
745! 2 : cs -(1.1+0.1p)*1.02**(-cs/7)*(log(1.02)/7)**2
746! 6 : p 0.1*1.02**(-cs/7)*(log(1.02)72)
747!
748! The two Hessian matrices do not overlap so the total number of nonzeros is
749! 5 per period. The structure using numerical indices for rows and columns and
750! running indices for the Hessian element is:
751!
752! 2 4 5 6
753! 2 1
754! 4
755! 5 3 5
756! 6 2 4
757!
758! and the same with names of variables and contributing equations
759! cs d r p
760! cs sdef
761! d
762! r revdef revdef
763! p sdef revdef
764!
765!
766! Normal Evaluation mode
767!
768 if ( n /= vpp*t ) then
769 write(*,*) 'Eval: Number of variables should be=',vpp*t,' but CONOPT uses',n
770 write(*,*) 'Number of periods=',t
771 pin_2dlagrval = 1; REturn
772 endif
773 if ( m /= epp*t+1 ) then
774 write(*,*) 'Eval: Number of equations should be=',epp*t+1,' but CONOPT uses',m
775 write(*,*) 'Number of periods=',t
776 pin_2dlagrval = 1; Return
777 endif
778 Do it = 1, t
779 is = hpp*(it-1)
780 ic = vpp*(it-1)
781 ie = epp*(it-1) + 1
782 cs = x(ic+2)
783 d = x(ic+4)
784 r = x(ic+5)
785 p = x(ic+6)
786 h1 = 1.1d0+0.1d0*p
787 h2 = 1.02d0**(-cs/7.d0)
788 hsvl(is+1) = -h1*h2*(log(1.02)/7.d0)**2 * u(ie+2) ! Sdef = equation 2
789 hsvl(is+2) = 0.1d0*h2*(log(1.02)/7.d0) * u(ie+2)
790 hsvl(is+3) = -250.d0/r**2 * u(ie+6) ! Revdef = equation 6
791 hsvl(is+4) = -1.d0 * u(ie+6)
792 hsvl(is+5) = 500.d0*d/ r**3 * u(ie+6)
793 enddo
794
795 pin_2dlagrval = 0
796
797End Function pin_2dlagrval
Main program. A simple setup and call of CONOPT.
Definition pinadd2.java:14
integer function std_status(modsta, solsta, iter, objval, usrmem)
Definition comdecl.f90:126
integer function std_message(smsg, dmsg, nmsg, llen, usrmem, msgv)
Definition comdecl.f90:243
integer function std_errmsg(rowno, colno, posno, msglen, usrmem, msg)
Definition comdecl.f90:286
integer function pin_fdeval(x, g, jac, rowno, jcnm, mode, ignerr, errcnt, n, nz, thread, usrmem)
Compute nonlinear terms and non-constant Jacobian elements.
Definition fvboth.f90:429
integer function pin_readmatrix(lower, curr, upper, vsta, type, rhs, esta, colsta, rowno, value, nlflag, n, m, nz, usrmem)
Define information about the model.
Definition fvboth.f90:161
integer function pin_solution(xval, xmar, xbas, xsta, yval, ymar, ybas, ysta, n, m, usrmem)
Definition fvboth.f90:535
integer(c_int) function coidef_message(cntvect, coi_message)
define callback routine for handling messages returned during the solution process.
Definition conopt.f90:1265
integer(c_int) function coidef_solution(cntvect, coi_solution)
define callback routine for returning the final solution values.
Definition conopt.f90:1238
integer(c_int) function coidef_status(cntvect, coi_status)
define callback routine for returning the completion status.
Definition conopt.f90:1212
integer(c_int) function coidef_readmatrix(cntvect, coi_readmatrix)
define callback routine for providing the matrix data to CONOPT.
Definition conopt.f90:1111
integer(c_int) function coidef_errmsg(cntvect, coi_errmsg)
define callback routine for returning error messages for row, column or Jacobian elements.
Definition conopt.f90:1291
integer(c_int) function coidef_fdeval(cntvect, coi_fdeval)
define callback routine for performing function and derivative evaluations.
Definition conopt.f90:1135
integer(c_int) function coidef_2dlagrstr(cntvect, coi_2dlagrstr)
define callback routine for providing the structure of the second derivatives of the Lagrangian.
Definition conopt.f90:1547
integer(c_int) function coidef_optfile(cntvect, optfile)
define callback routine for defining an options file.
Definition conopt.f90:928
integer(c_int) function coidef_2dlagrval(cntvect, coi_2dlagrval)
define callback routine for computing the values of the second derivatives of the Lagrangian.
Definition conopt.f90:1573
integer(c_int) function coidef_inistat(cntvect, inistat)
handling of the initial status values.
Definition conopt.f90:1023
integer(c_int) function coidef_license(cntvect, licint1, licint2, licint3, licstring)
define the License Information.
Definition conopt.f90:293
integer(c_int) function coidef_debug2d(cntvect, debug2d)
turn debugging of 2nd derivatives on and off.
Definition conopt.f90:534
integer(c_int) function coidef_numvar(cntvect, numvar)
defines the number of variables in the model.
Definition conopt.f90:97
integer(c_int) function coidef_numcon(cntvect, numcon)
defines the number of constraints in the model.
Definition conopt.f90:121
integer(c_int) function coidef_numnlnz(cntvect, numnlnz)
defines the Number of Nonlinear Nonzeros.
Definition conopt.f90:167
integer(c_int) function coidef_optdir(cntvect, optdir)
defines the Optimization Direction.
Definition conopt.f90:213
integer(c_int) function coidef_numnz(cntvect, numnz)
defines the number of nonzero elements in the Jacobian.
Definition conopt.f90:144
integer(c_int) function coidef_numhess(cntvect, numhess)
defines the Number of Hessian Nonzeros.
Definition conopt.f90:188
integer(c_int) function coidef_objcon(cntvect, objcon)
defines the Objective Constraint.
Definition conopt.f90:239
integer(c_int) function coi_create(cntvect)
initializes CONOPT and creates the control vector.
Definition conopt.f90:1726
integer(c_int) function coi_free(cntvect)
frees the control vector.
Definition conopt.f90:1749
integer(c_int) function coi_solve(cntvect)
method for starting the solving process of CONOPT.
Definition conopt.f90:1625
integer t
Definition pinadd2.f90:21
integer, parameter tmax
Definition pinadd2.f90:22
integer, dimension(tmax *vpp) xstas
Definition pinadd2.f90:27
integer, parameter epp
Definition pinadd2.f90:24
integer, parameter hpp
Definition pinadd2.f90:25
integer, dimension(tmax *epp) estat
Definition pinadd2.f90:28
integer, parameter tmin
Definition pinadd2.f90:22
integer, parameter vpp
Definition pinadd2.f90:23
integer solcalls
Definition comdecl.f90:15
integer sstat
Definition comdecl.f90:18
subroutine finalize
Definition comdecl.f90:79
integer stacalls
Definition comdecl.f90:14
subroutine flog(msg, code)
Definition comdecl.f90:62
integer mstat
Definition comdecl.f90:17
subroutine startup
Definition comdecl.f90:41
integer function pin_2dlagrstr(hsrw, hscl, nodrv, n, m, nhess, usrmem)
Specify the structure of the Lagrangian of the Hessian.
Definition pinadd2.f90:611
integer function pin_2dlagrval(x, u, hsrw, hscl, hsvl, nodrv, n, m, nhess, usrmem)
Compute the Lagrangian of the Hessian.
Definition pinadd2.f90:689