CONOPT
Loading...
Searching...
No Matches
postmo01.f90
Go to the documentation of this file.
1!> @file postmo01.f90
2!! @ingroup FORT1THREAD_EXAMPLES
3!!
4!!
5!! Model with derivatives that become constant after other variables are fixed.
6!!
7!! This is a CONOPT implementation of the GAMS model:
8!!
9!! @verbatim
10!! e1: log(x1) =E= x2;
11!! e2: exp(x3) =E= x1;
12!! max x2
13!! 0.01 <= x1 x1.l = 1
14!! -1.0 <= x2 <= 1; x2.l = 0
15!! x3.l = 0;
16!! @endverbatim
17!!
18!! The bounds on x2 prevent e1 from being posttriangular immediately. However, due to
19!! the monotonicity the bounds can be transferred to x1. Similarly, the bounds on x1
20!! can be moved to x2 and the model ends with one variable and no constraints.
21!!
22!! The transfer of bounds work as follows:
23!! e1: the inverval `-1 <= x2 <= 1` is transferred to `0.368 = exp(-1) <= x1 <= exp(1) = 2.718`
24!! that both are tighter than the input bounds.
25!! e2: the inverval `exp(-1) <= x1 <= exp(1)` from before is transferred to `-1 <= x3 <= 1`
26!! that again is tighter that the input bounds.
27!!
28!! The expected solution is `x2=1` (at upper bound), `x1=exp(x2)=exp(1)`, and `x3= log(x1) = 1`;
29!!
30!!
31!! For more information about the individual callbacks, please have a look at the source code.
32
33!> Main program. A simple setup and call of CONOPT
34!!
35Program postmo01
36
37 Use proginfo
38 Use coidef
39 implicit None
40!
41! Declare the user callback routines as Integer, External:
42!
43 Integer, External :: con_readmatrix ! Mandatory Matrix definition routine defined below
44 Integer, External :: con_fdeval ! Function and Derivative evaluation routine
45 ! needed a nonlinear model.
46 Integer, External :: con_fdinterval ! Function and Derivative evaluation routine
47 ! optional for a nonlinear model.
48 Integer, External :: std_status ! Standard callback for displaying solution status
49 Integer, External :: std_solution ! Standard callback for displaying solution values
50 Integer, External :: std_message ! Standard callback for managing messages
51 Integer, External :: std_errmsg ! Standard callback for managing error messages
52#if defined(itl)
53!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Con_ReadMatrix
54!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Con_FDEval
55!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Con_FDInterval
56!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Status
57!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Solution
58!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Message
59!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_ErrMsg
60#endif
61!
62! Control vector
63!
64 INTEGER, Dimension(:), Pointer :: cntvect
65 INTEGER :: coi_error
66!
67! Create and initialize a Control Vector
68!
69 call startup
70
71 coi_error = coi_createfort( cntvect )
72!
73! Tell CONOPT about the size of the model by populating the Control Vector:
74!
75 coi_error = max( coi_error, coidef_numvar( cntvect, 3 ) ) ! # variables
76 coi_error = max( coi_error, coidef_numcon( cntvect, 2 ) ) ! # constraints
77 coi_error = max( coi_error, coidef_numnz( cntvect, 4 ) ) ! # nonzeros in the Jacobian
78 coi_error = max( coi_error, coidef_numnlnz( cntvect, 2 ) ) ! # of which are nonlinear
79 coi_error = max( coi_error, coidef_optdir( cntvect, 1 ) ) ! Maximize
80 coi_error = max( coi_error, coidef_objvar( cntvect, 2 ) ) ! Objective is variable 2
81 coi_error = max( coi_error, coidef_optfile( cntvect, 'postmo01.opt' ) )
82!
83! Tell CONOPT about the callback routines:
84!
85 coi_error = max( coi_error, coidef_readmatrix( cntvect, con_readmatrix ) )
86 coi_error = max( coi_error, coidef_fdeval( cntvect, con_fdeval ) )
87 coi_error = max( coi_error, coidef_fdinterval( cntvect, con_fdinterval ) )
88 coi_error = max( coi_error, coidef_status( cntvect, std_status ) )
89 coi_error = max( coi_error, coidef_solution( cntvect, std_solution ) )
90 coi_error = max( coi_error, coidef_message( cntvect, std_message ) )
91 coi_error = max( coi_error, coidef_errmsg( cntvect, std_errmsg ) )
92
93#if defined(LICENSE_INT_1) && defined(LICENSE_INT_2) && defined(LICENSE_INT_3) && defined(LICENSE_TEXT)
94 coi_error = max( coi_error, coidef_license( cntvect, license_int_1, license_int_2, license_int_3, license_text) )
95#endif
96
97 If ( coi_error .ne. 0 ) THEN
98 write(*,*)
99 write(*,*) '**** Fatal Error while loading CONOPT Callback routines.'
100 write(*,*)
101 call flog( "Skipping Solve due to setup errors", 1 )
102 ENDIF
103!
104! Save the solution so we can check the duals:
105!
106 do_allocate = .true.
107!
108! Start CONOPT:
109!
110 coi_error = coi_solve( cntvect )
111
112 write(*,*)
113 write(*,*) 'End of postmo01 example. Return code=',coi_error
114
115 If ( coi_error /= 0 ) then
116 call flog( "Errors encountered during solution", 1 )
117 elseif ( stacalls == 0 .or. solcalls == 0 ) then
118 call flog( "Status or Solution routine was not called", 1 )
119 elseif ( sstat /= 1 .or. mstat /= 2 ) then
120 call flog( "Solver and Model Status was not as expected (1,2)", 1 )
121 elseif ( abs( obj-1.0d0 ) > 0.000001d0 ) then
122 call flog( "Incorrect objective returned", 1 )
123 Else
124 Call checkdual( 'postmo01', maximize )
125 endif
126
127 if ( coi_free(cntvect) /= 0 ) call flog( "Error while freeing control vector",1)
128
129 call flog( "Successful Solve", 0 )
130
131End Program postmo01
132!
133! ============================================================================
134! Define information about the model:
135!
136
137!> Define information about the model
138!!
139!! @include{doc} readMatrix_params.dox
140Integer Function con_readmatrix( lower, curr, upper, vsta, type, rhs, esta, &
141 colsta, rowno, value, nlflag, n, m, nz, &
142 usrmem )
143#if defined(itl)
144!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Con_ReadMatrix
145#endif
146 implicit none
147 integer, intent (in) :: n ! number of variables
148 integer, intent (in) :: m ! number of constraints
149 integer, intent (in) :: nz ! number of nonzeros
150 real*8, intent (in out), dimension(n) :: lower ! vector of lower bounds
151 real*8, intent (in out), dimension(n) :: curr ! vector of initial values
152 real*8, intent (in out), dimension(n) :: upper ! vector of upper bounds
153 integer, intent (in out), dimension(n) :: vsta ! vector of initial variable status
154 ! (not defined here)
155 integer, intent (out), dimension(m) :: type ! vector of equation types
156 integer, intent (in out), dimension(m) :: esta ! vector of initial equation status
157 ! (not defined here)
158 real*8, intent (in out), dimension(m) :: rhs ! vector of right hand sides
159 integer, intent (in out), dimension(n+1) :: colsta ! vector with start of column indices
160 integer, intent (out), dimension(nz) :: rowno ! vector of row numbers
161 integer, intent (in out), dimension(nz) :: nlflag ! vector of nonlinearity flags
162 real*8, intent (in out), dimension(nz) :: value ! vector of matrix values
163 real*8 usrmem(*) ! optional user memory
164!
165! Information about Variables:
166! Default: Lower = -Inf, Curr = 0, and Upper = +inf.
167! Default: the status information in Vsta is not used.
168!
169 lower(1) = 0.01d0; curr(1) = 1.0d0
170 lower(2) = -1.0d0; curr(2) = 0.0d0; upper(2) = 1.0d0
171 curr(3) = 0.0d0
172!
173! Information about Constraints:
174! Default: Rhs = 0
175! Default: the status information in Esta and the function
176! value in FV are not used.
177! Default: Type: There is no default.
178! 0 = Equality,
179! 1 = Greater than or equal,
180! 2 = Less than or equal,
181! 3 = Non binding.
182!
183 type(1) = 0
184 type(2) = 0
185!
186! Information about the Jacobian. We use the standard method with
187! Rowno, Value, Nlflag and Colsta and we do not use Colno.
188!
189! Colsta = Start of column indices (No Defaults):
190! Rowno = Row indices
191! Value = Value of derivative (by default only linear
192! derivatives are used)
193! Nlflag = 0 for linear and 1 for nonlinear derivative
194! (not needed for completely linear models)
195!
196! Indices
197! x(1) x(2) x(3)
198! 1: 1 3
199! 2: 2 4
200! e1: log(x1) =E= x2;
201! e2: exp(x3) =E= x1;
202!
203 colsta(1) = 1
204 colsta(2) = 3
205 colsta(3) = 4
206 colsta(4) = 5
207 rowno(1) = 1
208 rowno(2) = 2
209 rowno(3) = 1
210 rowno(4) = 2
211!
212! Nonlinearity Structure: L = 0 are linear and NL = 1 are nonlinear
213! x(1) x(2) x(3)
214! 1: NL L
215! 2: L NL
216!
217 nlflag(1) = 1
218 nlflag(2) = 0
219 nlflag(3) = 0
220 nlflag(4) = 1
221!
222! Value (Linear only)
223! x(1) x(2) x(3)
224! 1: NL -1.0
225! 2: -1.0 NL
226!
227 value(2) = -1.d0
228 value(3) = -1.d0
229
230 con_readmatrix = 0 ! Return value means OK
231
232end Function con_readmatrix
233!
234!==========================================================================
235! Compute nonlinear terms and non-constant Jacobian elements
236!
237
238!> Compute nonlinear terms and non-constant Jacobian elements
239!!
240!! @include{doc} fdeval_params.dox
241Integer Function con_fdeval( x, g, jac, rowno, jcnm, mode, ignerr, errcnt, &
242 n, nz, thread, usrmem )
243#if defined(itl)
244!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Con_FDEval
245#endif
246 implicit none
247 integer, intent (in) :: n ! number of variables
248 integer, intent (in) :: rowno ! number of the row to be evaluated
249 integer, intent (in) :: nz ! number of nonzeros in this row
250 real*8, intent (in), dimension(n) :: x ! vector of current solution values
251 real*8, intent (in out) :: g ! constraint value
252 real*8, intent (in out), dimension(n) :: jac ! vector of derivatives for current constraint
253 integer, intent (in), dimension(nz) :: jcnm ! list of variables that appear nonlinearly
254 ! in this row. Ffor information only.
255 integer, intent (in) :: mode ! evaluation mode: 1 = function value
256 ! 2 = derivatives, 3 = both
257 integer, intent (in) :: ignerr ! if 1 then errors can be ignored as long
258 ! as errcnt is incremented
259 integer, intent (in out) :: errcnt ! error counter to be incremented in case
260 ! of function evaluation errors.
261 integer, intent (in) :: thread
262 real*8 usrmem(*) ! optional user memory
263 if ( rowno .eq. 1 ) then
264!
265! e1: log(x1) =E= x2;
266!
267! Mode = 1 or 3: Function value
268!
269 if ( mode .eq. 1 .or. mode .eq. 3 ) then
270 g = log(x(1))
271 endif
272!
273! Mode = 2 or 3: Derivatives
274!
275 if ( mode .eq. 2 .or. mode .eq. 3 ) then
276 jac(1) = 1.0d0/x(1)
277 endif
278 con_fdeval = 0
279 else if ( rowno .eq. 2 ) then
280!
281! e2: exp(x3) =E= x1;
282!
283! Mode = 1 or 3: Function value
284!
285 if ( mode .eq. 1 .or. mode .eq. 3 ) then
286 g = exp(x(3))
287 endif
288!
289! Mode = 2 or 3: Derivatives
290!
291 if ( mode .eq. 2 .or. mode .eq. 3 ) then
292 jac(3) = exp(x(3))
293 endif
294 con_fdeval = 0
295 Else
296 con_fdeval = 1 ! Should not happen
297 endif
298
299end Function con_fdeval
300
301
302!> Evaluating nonlinear functions and derivatives on an interval. Used in preprocessing
303!!
304!! @include{doc} fdinterval_params.dox
305Integer Function con_fdinterval( XMIN, XMAX, GMIN, GMAX, &
306 JMIN, JMAX, ROWNO, JCNM, &
307 MODE, PINF, N, NJ, USRMEM )
308#if defined(itl)
309!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Con_FDInterval
310#endif
311 Implicit None
312 INTEGER, Intent(IN) :: rowno, mode, n, nj
313 INTEGER, Dimension(NJ), Intent(IN) :: jcnm
314 real*8, Dimension(N), Intent(IN) :: xmin, xmax
315 real*8, Intent(IN OUT) :: gmin, gmax
316 real*8, Dimension(N), Intent(IN OUT) :: jmin, jmax
317 real*8, Intent(IN) :: pinf
318 real*8, Intent(IN OUT) :: usrmem(*)
319
320 if ( rowno .eq. 1 ) then
321!
322! e1: log(x1) =E= x2;
323!
324! Mode = 1 or 3. Function value
325!
326 if ( mode .eq. 1 .or. mode .eq. 3 ) then
327 gmin = log(xmin(1))
328 gmax = log(xmax(1))
329 endif
330!
331! Mode = 2 or 3: Derivative values:
332!
333 if ( mode .eq. 2 .or. mode .eq. 3 ) then
334 jmin(1) = 1.0d0/xmax(1)
335 jmax(1) = 1.0d0/xmin(1)
336 endif
338 else if ( rowno .eq. 2 ) then
339!
340! e2: exp(x3) =E= x1;
341!
342! Mode = 1 or 3. Function value
343!
344 if ( mode .eq. 1 .or. mode .eq. 3 ) then
345 gmin = exp(xmin(3))
346 gmax = exp(xmax(3))
347 endif
348!
349! Mode = 2 or 3: Derivative values:
350!
351 if ( mode .eq. 2 .or. mode .eq. 3 ) then
352 jmin(3) = exp(xmin(3))
353 jmax(3) = exp(xmax(3))
354 endif
356 else
357!
358! There are no other rows:
359!
361 endif
362
363end Function con_fdinterval
integer function std_solution(xval, xmar, xbas, xsta, yval, ymar, ybas, ysta, n, m, usrmem)
Definition comdecl.f90:128
integer function std_status(modsta, solsta, iter, objval, usrmem)
Definition comdecl.f90:82
subroutine checkdual(case, minmax)
Definition comdecl.f90:365
integer function std_message(smsg, dmsg, nmsg, llen, usrmem, msgv)
Definition comdecl.f90:203
integer function std_errmsg(rowno, colno, posno, msglen, usrmem, msg)
Definition comdecl.f90:248
integer function con_readmatrix(lower, curr, upper, vsta, type, rhs, esta, colsta, rowno, value, nlflag, n, m, nz, usrmem)
Define information about the model.
Definition const01.f90:133
integer function con_fdeval(x, g, jac, rowno, jcnm, mode, ignerr, errcnt, n, nz, thread, usrmem)
Compute nonlinear terms and non-constant Jacobian elements.
Definition const01.f90:238
integer function con_fdinterval(xmin, xmax, gmin, gmax, jmin, jmax, rowno, jcnm, mode, pinf, n, nj, usrmem)
Evaluating nonlinear functions and derivatives on an interval. Used in preprocessing.
Definition const01.f90:291
integer function coidef_fdeval(cntvect, coi_fdeval)
define callback routine for performing function and derivative evaluations.
integer function coidef_errmsg(cntvect, coi_errmsg)
define callback routine for returning error messages for row, column or Jacobian elements.
integer function coidef_message(cntvect, coi_message)
define callback routine for handling messages returned during the solution process.
integer function coidef_readmatrix(cntvect, coi_readmatrix)
define callback routine for providing the matrix data to CONOPT.
integer function coidef_status(cntvect, coi_status)
define callback routine for returning the completion status.
integer function coidef_solution(cntvect, coi_solution)
define callback routine for returning the final solution values.
integer function coidef_optfile(cntvect, optfile)
define callback routine for defining an options file.
integer function coidef_fdinterval(cntvect, coi_fdinterval)
define callback routine for performing function and derivative evaluations on intervals.
integer function coidef_license(cntvect, licint1, licint2, licint3, licstring)
define the License Information.
Definition coistart.f90:680
integer function coidef_numvar(cntvect, numvar)
defines the number of variables in the model.
Definition coistart.f90:358
integer function coidef_numnz(cntvect, numnz)
defines the number of nonzero elements in the Jacobian.
Definition coistart.f90:437
integer function coidef_optdir(cntvect, optdir)
defines the Optimization Direction.
Definition coistart.f90:552
integer function coidef_numnlnz(cntvect, numnlnz)
defines the Number of Nonlinear Nonzeros.
Definition coistart.f90:476
integer function coidef_numcon(cntvect, numcon)
defines the number of constraints in the model.
Definition coistart.f90:398
integer function coidef_objvar(cntvect, objvar)
defines the Objective Variable.
Definition coistart.f90:586
integer function coi_solve(cntvect)
method for starting the solving process of CONOPT.
Definition coistart.f90:14
#define nj
Definition mp_trans.c:46
real *8 obj
Definition comdecl.f90:10
integer solcalls
Definition comdecl.f90:9
integer sstat
Definition comdecl.f90:12
integer stacalls
Definition comdecl.f90:8
subroutine flog(msg, code)
Definition comdecl.f90:56
logical do_allocate
Definition comdecl.f90:21
integer, parameter maximize
Definition comdecl.f90:25
integer mstat
Definition comdecl.f90:11
subroutine startup
Definition comdecl.f90:35
program postmo01
Main program. A simple setup and call of CONOPT.
Definition postmo01.f90:35