CONOPT
Loading...
Searching...
No Matches
mp_elec2.f90
Go to the documentation of this file.
1!> @file mp_elec2.f90
2!! @ingroup FORTOPENMP_EXAMPLES
3!!
4!! @copydoc elec2.f90
5
6#if defined(_WIN32) && !defined(_WIN64)
7#define dec_directives_win32
8#endif
9
10Module hesscalls
11 Integer :: Hcalls
12End Module hesscalls
13
14Module random
15 Integer :: seed
16End Module random
17
18!> Main program. A simple setup and call of CONOPT
19!!
20Program electron
21
23 Use conopt
24 Use hesscalls
25 Use omp_lib
26 Use random
27 implicit None
28!
29! Declare the user callback routines as Integer, External:
30!
31 Integer, External :: elec_readmatrix ! Mandatory Matrix definition routine defined below
32 Integer, External :: elec_fdeval ! Function and Derivative evaluation routine
33 ! needed a nonlinear model.
34 Integer, External :: std_status ! Standard callback for displaying solution status
35 Integer, External :: std_solution ! Standard callback for displaying solution values
36 Integer, External :: std_message ! Standard callback for managing messages
37 Integer, External :: std_errmsg ! Standard callback for managing error messages
38 Integer, External :: elec_2dlagrsize ! Callback for second derivatives size
39 Integer, External :: elec_2dlagrstr ! Callback for second derivatives structure
40 Integer, External :: elec_2dlagrval ! Callback for second derivatives values
41#ifdef dec_directives_win32
42!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_ReadMatrix
43!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_FDEval
44!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Status
45!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Solution
46!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Message
47!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_ErrMsg
48!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_2DLagrSize
49!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_2DLagrStr
50!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_2DLagrVal
51#endif
52!
53! Control vector
54!
55 INTEGER, Dimension(:), Pointer :: cntvect
56 INTEGER :: coi_error
57!
58! The model shown here in GAMS format
59!
60!
61!Set i electrons /i1 * i%np%/
62! ut(i,i) upper triangular part;
63!
64!Alias (i,j);
65!ut(i,j)$(ord(j) > ord(i)) = yes;
66!
67!Variables x(i) x-coordinate of the electron
68! y(i) y-coordinate of the electron
69! z(i) z-coordinate of the electron
70! potential Coulomb potential;
71!
72!Equations obj objective
73! ball(i) points on unit ball;
74!
75!obj.. potential =e=
76! sum{ut(i,j), 1.0/sqrt(sqr(x[i]-x[j]) + sqr(y[i]-y[j]) + sqr(z[i]-z[j]))};
77!
78!ball(i).. sqr(x(i)) + sqr(y(i)) + sqr(z(i)) =e= 1;
79!
80!
81!* Set the starting point to a quasi-uniform distribution
82!* of electrons on a unit sphere
83!
84!scalar pi a famous constant;
85!pi = 2*arctan(inf);
86!
87!parameter theta(i), phi(i);
88!theta(i) = 2*pi*uniform(0,1);
89!phi(i) = pi*uniform(0,1);
90!
91!x.l(i) = cos(theta(i))*sin(phi(i));
92!y.l(i) = sin(theta(i))*sin(phi(i));
93!z.l(i) = cos(phi(i));
94!
95 Integer :: ne ! Number of Electrons
96
97 real*8 time0, time1, time2
98!
99! Create and initialize a Control Vector
100!
101 call startup
102
103 coi_error = coi_create( cntvect )
104!
105! Tell CONOPT about the size of the model by populating the Control Vector:
106!
107 ne = 150 ! Number of electrons
108 coi_error = max( coi_error, coidef_numvar( cntvect, 3*ne ) ) ! # variables
109 coi_error = max( coi_error, coidef_numcon( cntvect, ne+1 ) ) ! # constraints
110 coi_error = max( coi_error, coidef_numnz( cntvect, 6*ne ) ) ! # nonzeros in the Jacobian
111 coi_error = max( coi_error, coidef_numnlnz( cntvect, 6*ne ) ) ! # of which are nonlinear
112 coi_error = max( coi_error, coidef_optdir( cntvect, -1 ) ) ! Minimize
113 coi_error = max( coi_error, coidef_objcon( cntvect, ne+1 ) ) ! Objective is constraint NE+1
114 coi_error = max( coi_error, coidef_debug2d( cntvect, 0 ) ) ! turn 2nd derivative debugging on or off
115 coi_error = max( coi_error, coidef_optfile( cntvect, 'mp_elec2.opt' ) )
116!
117! Tell CONOPT about the callback routines:
118!
119 coi_error = max( coi_error, coidef_readmatrix( cntvect, elec_readmatrix ) )
120 coi_error = max( coi_error, coidef_fdeval( cntvect, elec_fdeval ) )
121 coi_error = max( coi_error, coidef_status( cntvect, std_status ) )
122 coi_error = max( coi_error, coidef_solution( cntvect, std_solution ) )
123 coi_error = max( coi_error, coidef_message( cntvect, std_message ) )
124 coi_error = max( coi_error, coidef_errmsg( cntvect, std_errmsg ) )
125 coi_error = max( coi_error, coidef_2dlagrsize( cntvect, elec_2dlagrsize ) )
126 coi_error = max( coi_error, coidef_2dlagrstr( cntvect, elec_2dlagrstr ) )
127 coi_error = max( coi_error, coidef_2dlagrval( cntvect, elec_2dlagrval ) )
128
129#if defined(CONOPT_LICENSE_INT_1) && defined(CONOPT_LICENSE_INT_2) && defined(CONOPT_LICENSE_INT_3) && defined(CONOPT_LICENSE_TEXT)
130 coi_error = max( coi_error, coidef_license( cntvect, conopt_license_int_1, conopt_license_int_2, conopt_license_int_3, conopt_license_text) )
131#endif
132
133 If ( coi_error .ne. 0 ) THEN
134 write(*,*)
135 write(*,*) '**** Fatal Error while loading CONOPT Callback routines.'
136 write(*,*)
137 call flog( "Skipping Solve due to setup errors", 1 )
138 ENDIF
139!
140! Start CONOPT with enough space for the Hessian of the Lagrangian -- first time single thread
141!
142 coi_error = max( coi_error, coidef_hessfac( cntvect, 3.01d0*(ne+1)/4.d0 ) ) ! enough to allow Hessian to be use
143 hcalls = 0
144 seed = 12345
145 time0 = omp_get_wtime()
146 coi_error = coi_solve( cntvect )
147 time1 = omp_get_wtime() - time0
148
149 write(*,*)
150 write(*,*) 'End of Electron example one thread. Return code=',coi_error
151
152 If ( coi_error /= 0 ) then
153 call flog( "One Thread: Errors encountered during solution", 1 )
154 elseif ( stacalls == 0 .or. solcalls == 0 ) then
155 call flog( "One Thread: Status or Solution routine was not called", 1 )
156 elseif ( sstat /= 1 .or. mstat /= 2 ) then
157 call flog( "One Thread: Solver and Model Status was not as expected (1,2)", 1 )
158 elseif ( hcalls == 0 ) then
159 call flog( "One Thread: Solve did not use 2nd derivatives but should have enough memory", 1 )
160 endif
161!
162! Start CONOPT again -- this time using multiple threads:
163!
164 seed = 12345 ! Make sure we get the same model the second time
165 coi_error = max( coi_error, coidef_threads( cntvect, 0 ) ) ! 0 means use as many threads as you can
166 time0 = omp_get_wtime()
167 coi_error = coi_solve( cntvect )
168 time2 = omp_get_wtime() - time0
169
170 write(*,*)
171 write(*,*) 'End of Electron example multi threads. Return code=',coi_error
172
173 If ( coi_error /= 0 ) then
174 call flog( "Multi thread: Errors encountered during solution", 1 )
175 elseif ( stacalls == 0 .or. solcalls == 0 ) then
176 call flog( "Multi thread: Status or Solution routine was not called", 1 )
177 elseif ( sstat /= 1 .or. mstat /= 2 ) then
178 call flog( "Multi thread: Solver and Model Status was not as expected (1,2)", 1 )
179 elseif ( hcalls == 0 ) then
180 call flog( "Multi thread: Solve did not use 2nd derivatives but should have enough memory", 1 )
181 endif
182
183 if ( coi_free( cntvect ) /= 0 ) call flog( "Error while freeing control vector", 1 )
184
185 write(*,*)
186 write(*,"('Time for single thread',f10.3)") time1
187 write(*,"('Time for multi thread',f10.3)") time2
188 write(*,"('Speedup ',f10.3)") time1/time2
189 write(*,"('Efficiency ',f10.3)") time1/time2/omp_get_max_threads()
190
191 call flog( "Successful Solve", 0 )
192
193End Program electron
194
195REAL FUNCTION rndx( )
196!
197! Defines a pseudo random number between 0 and 1
198!
199 Use random
200 IMPLICIT NONE
201
202 seed = mod(seed*1027+25,1048576)
203 rndx = float(seed)/float(1048576)
204
205END FUNCTION rndx
206!
207! ============================================================================
208! Define information about the model:
209!
210
211!> Define information about the model
212!!
213!! @include{doc} readMatrix_params.dox
214Integer Function elec_readmatrix( lower, curr, upper, vsta, type, rhs, esta, &
215 colsta, rowno, value, nlflag, n, m, nz, &
216 usrmem )
217#ifdef dec_directives_win32
218!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_ReadMatrix
219#endif
220 implicit none
221 integer, intent (in) :: n ! number of variables
222 integer, intent (in) :: m ! number of constraints
223 integer, intent (in) :: nz ! number of nonzeros
224 real*8, intent (in out), dimension(n) :: lower ! vector of lower bounds
225 real*8, intent (in out), dimension(n) :: curr ! vector of initial values
226 real*8, intent (in out), dimension(n) :: upper ! vector of upper bounds
227 integer, intent (in out), dimension(n) :: vsta ! vector of initial variable status
228 ! (not defined here)
229 integer, intent (out), dimension(m) :: type ! vector of equation types
230 integer, intent (in out), dimension(m) :: esta ! vector of initial equation status
231 ! (not defined here)
232 real*8, intent (in out), dimension(m) :: rhs ! vector of right hand sides
233 integer, intent (in out), dimension(n+1) :: colsta ! vector with start of column indices
234 integer, intent (out), dimension(nz) :: rowno ! vector of row numbers
235 integer, intent (in out), dimension(nz) :: nlflag ! vector of nonlinearity flags
236 real*8, intent (in out), dimension(nz) :: value ! vector of matrix values
237 real*8 usrmem(*) ! optional user memory
238
239 Integer :: ne
240 Integer :: i, k
241 real*8, parameter :: pi = 3.141592
242 real*8 :: theta, phi
243 Real, External :: rndx
244
245 ne = n / 3
246!
247! Information about Variables:
248! Default: Lower = -Inf, Curr = 0, and Upper = +inf.
249! Default: the status information in Vsta is not used.
250!
251 DO i = 1, ne
252 theta = rndx()
253 phi = rndx()
254 curr(i ) = cos(theta)*sin(phi)
255 curr(i+ ne) = sin(theta)*sin(phi)
256 curr(i+2*ne) = cos(phi)
257 enddo
258!
259! Information about Constraints:
260! Default: Rhs = 0
261! Default: the status information in Esta and the function
262! value in FV are not used.
263! Default: Type: There is no default.
264! 0 = Equality,
265! 1 = Greater than or equal,
266! 2 = Less than or equal,
267! 3 = Non binding.
268!
269! Constraint 1 (Objective)
270! Rhs = 0.0 and type Non binding
271!
272 DO i = 1, ne
273 Type(i) = 0
274 rhs(i) = 1.d0
275 Enddo
276 type(ne+1) = 3
277!
278! Information about the Jacobian. We have to define Rowno, Value,
279! Nlflag and Colsta.
280!
281! Colsta = Start of column indices (No Defaults):
282! Rowno = Row indices
283! Value = Value of derivative (by default only linear
284! derivatives are used)
285! Nlflag = 0 for linear and 1 for nonlinear derivative
286! (not needed for completely linear models)
287!
288! Indices
289! x(1) x(2) .. y(1) y(2) .. z(1) z(2) ..
290! 1: 1 2*Ne+1 3*Ne+1
291! 2: 3 2*Ne+3 3*Ne+3
292! ..
293! Obj: 2 4 2*Ne+2 2*Ne+4 3*Ne+2 3*Ne+4
294!
295! Nonlinearity Structure: L = 0 are linear and NL = 1 are nonlinear
296! All nonzeros are nonlinear
297!
298 DO i = 1, n+1
299 colsta(i) = 2*i-1
300 enddo
301 k = 0
302 DO i = 1, ne ! x variablex
303 k = k + 1
304 rowno(k) = i ! Ball constraint
305 nlflag(k) = 1
306 k = k + 1
307 rowno(k) = ne+1 ! Objective
308 nlflag(k) = 1
309 enddo
310 DO i = 1, ne ! y variablex
311 k = k + 1
312 rowno(k) = i ! Ball constraint
313 nlflag(k) = 1
314 k = k + 1
315 rowno(k) = ne+1 ! Objective
316 nlflag(k) = 1
317 enddo
318 DO i = 1, ne ! z variablex
319 k = k + 1
320 rowno(k) = i ! Ball constraint
321 nlflag(k) = 1
322 k = k + 1
323 rowno(k) = ne+1 ! Objective
324 nlflag(k) = 1
325 enddo
326
327 elec_readmatrix = 0 ! Return value means OK
328
329end Function elec_readmatrix
330!
331!==========================================================================
332! Compute nonlinear terms and non-constant Jacobian elements
333!
334
335!> Compute nonlinear terms and non-constant Jacobian elements
336!!
337!! @include{doc} fdeval_params.dox
338Integer Function elec_fdeval( x, g, jac, rowno, jcnm, mode, ignerr, errcnt, &
339 n, nz, thread, usrmem )
340#ifdef dec_directives_win32
341!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_FDEval
342#endif
343 implicit none
344 integer, intent (in) :: n ! number of variables
345 integer, intent (in) :: rowno ! number of the row to be evaluated
346 integer, intent (in) :: nz ! number of nonzeros in this row
347 real*8, intent (in), dimension(n) :: x ! vector of current solution values
348 real*8, intent (in out) :: g ! constraint value
349 real*8, intent (in out), dimension(n) :: jac ! vector of derivatives for current constraint
350 integer, intent (in), dimension(nz) :: jcnm ! list of variables that appear nonlinearly
351 ! in this row. Ffor information only.
352 integer, intent (in) :: mode ! evaluation mode: 1 = function value
353 ! 2 = derivatives, 3 = both
354 integer, intent (in) :: ignerr ! if 1 then errors can be ignored as long
355 ! as errcnt is incremented
356 integer, intent (in out) :: errcnt ! error counter to be incremented in case
357 ! of function evaluation errors.
358 integer, intent (in) :: thread
359 real*8 usrmem(*) ! optional user memory
360
361 Integer :: ne
362 Integer :: i, j
363 real*8 :: dist, dist32, tx, ty, tz
364
365 ne = n / 3
366!
367! Row NE+1: the objective function is nonlinear
368!
369 if ( rowno == ne+1 ) then
370!
371! Mode = 1 or 3. Function value:
372!
373 if ( mode .eq. 1 .or. mode .eq. 3 ) then
374 g = 0.d0
375 do i = 1, ne-1
376 do j = i+1,ne
377 dist = (x(i)-x(j))**2 + (x(i+ne)-x(j+ne))**2 + (x(i+2*ne)-x(j+2*ne))**2
378 g = g + 1.d0/sqrt(dist)
379 enddo
380 enddo
381 endif
382!
383! Mode = 2 or 3: Derivative values: w.r.t. x: 2*(x(i)-x(j))*(-1/2)*dist(-3/2)
384!
385 if ( mode .eq. 2 .or. mode .eq. 3 ) then
386 do i = 1, 3*ne
387 jac(i) = 0.d0
388 enddo
389 do i = 1, ne-1
390 do j = i+1,ne
391 dist = (x(i)-x(j))**2 + (x(i+ne)-x(j+ne))**2 + (x(i+2*ne)-x(j+2*ne))**2
392 dist32 = (1.d0/sqrt(dist))**3
393 tx = -(x(i)-x(j))*dist32
394 ty = -(x(i+ne)-x(j+ne))*dist32
395 tz = -(x(i+2*ne)-x(j+2*ne))*dist32
396 jac(i) = jac(i) + tx
397 jac(j) = jac(j) - tx
398 jac(i+ne) = jac(i+ne) + ty
399 jac(j+ne) = jac(j+ne) - ty
400 jac(i+2*ne) = jac(i+2*ne) + tz
401 jac(j+2*ne) = jac(j+2*ne) - tz
402 enddo
403 enddo
404 endif
405!
406 Else ! this is ball constraint rowno
407!
408! Mode = 1 or 3. Function value:
409!
410 i = rowno
411 if ( mode .eq. 1 .or. mode .eq. 3 ) then
412 g = x(i)**2 + x(i+ne)**2 + x(i+2*ne)**2
413 endif
414!
415! Mode = 2 or 3: Derivative values:
416!
417 if ( mode .eq. 2 .or. mode .eq. 3 ) then
418 jac(i) = 2.d0*x(i)
419 jac(i+ne) = 2.d0*x(i+ne)
420 jac(i+2*ne) = 2.d0*x(i+2*ne)
421 endif
422
423 endif
424 elec_fdeval = 0
425
426end Function elec_fdeval
427
428Integer Function elec_2dlagrsize( NODRV, NumVar, NumCon, NumHess, MaxHess, UsrMem )
429#ifdef dec_directives_win32
430!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_2DLagrSize
431#endif
432 Use hesscalls
433 Implicit None
434
435 Integer, Intent (IN) :: numvar, numcon, maxhess
436 Integer, Intent (IN OUT) :: nodrv, numhess
437 real*8, Intent(IN OUT) :: usrmem(*)
438!
439! Sizing call -- the hessian is completely dense
440!
441 numhess = numvar * (numvar+1)/2
443
444End Function elec_2dlagrsize
445
446
447!> Specify the structure of the Lagrangian of the Hessian
448!!
449!! @include{doc} 2DLagrStr_params.dox
450Integer Function elec_2dlagrstr( HSRW, HSCL, NODRV, NumVar, NumCon, NumHess, UsrMem )
451#ifdef dec_directives_win32
452!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_2DLagrStr
453#endif
454 Use hesscalls
455 Implicit None
456
457 Integer, Intent (IN) :: numvar, numcon, numhess
458 Integer, Intent (IN) :: nodrv
459 Integer, Dimension(*) :: hsrw, hscl
460 real*8, Intent(IN OUT) :: usrmem(*)
461
462 integer :: i, j, k
463!
464! Define structure of Hessian: A dense lower-triangular matrix
465!
466 k = 0
467 do i = 1, numvar
468 do j = i, numvar
469 k = k + 1
470 hsrw(k) = j
471 hscl(k) = i
472 enddo
473 enddo
475
476End Function elec_2dlagrstr
477
478
479!> Compute the Lagrangian of the Hessian
480!!
481!! @include{doc} 2DLagrVal_params.dox
482Integer Function elec_2dlagrval( X, U, HSRW, HSCL, HSVL, NODRV, NumVar, NumCon, NumHess, UsrMem )
483#ifdef dec_directives_win32
484!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Elec_2DLagrVal
485#endif
486 Use hesscalls
487 Implicit None
488
489 Integer, Intent (IN) :: numvar, numcon, numhess
490 Integer, Intent (IN OUT) :: nodrv
491 real*8, Dimension(NumVar), Intent (IN) :: x
492 real*8, Dimension(NumCon), Intent (IN) :: u
493 Integer, Dimension(NumHess), Intent (IN) :: hsrw, hscl
494 real*8, Dimension(NumHess), Intent (Out) :: hsvl
495 real*8, Intent(IN OUT) :: usrmem(*)
496
497 Integer :: ne ! Number of electrons
498 integer :: k, l, ix, iy, iz, jx, jy, jz
499 real*8 :: tx, ty, tz, dist, distsq, dist3, dist5
500!
501! Evaluation of 2nd derivatives. Hsvl is zero on entry:
502!
503 ne = numvar / 3
504 hcalls = hcalls + 1
505 k = 0
506! do i = 1, N
507! do j = i, N
508! k = k + 1
509! Hsvl(k) = 0.d0
510! enddo
511! enddo
512 do l = 1, ne ! constraint no l with 3 elements on the diagonal, each with value 2.0
513 k = pos(l,l) ! 1+(l-1)*(2*N+2-l)/2 ! variable x(l)
514 hsvl(k) = hsvl(k) + 2.d0*u(l)
515 k = pos(l+ne,l+ne) ! 1+(l+NE-1)*(2*N+2-(l+NE))/2 ! variable y(l)
516 hsvl(k) = hsvl(k) + 2.d0*u(l)
517 k = pos(l+2*ne,l+2*ne) ! 1+(l+2*NE-1)*(2*N+2-(l+2*NE))/2 ! variable z(l)
518 hsvl(k) = hsvl(k) + 2.d0*u(l)
519 enddo
520 if ( u(ne+1) /= 0.0d0 ) Then ! Nonzero dual on the objective
521 do ix = 1, ne-1
522 iy = ix + ne
523 iz = iy + ne
524 do jx = ix+1, ne
525 jy = jx + ne
526 jz = jy + ne
527! Objective computation:
528! dist = (x(i)-x(j))**2 + (x(i+NE)-x(j+NE))**2 + (x(i+2*NE)-x(j+2*NE))**2
529! g = g + 1.d0/sqrt(dist)
530 tx = x(ix)-x(jx) ! x1 - x2
531 ty = x(iy)-x(jy) ! y1 - y2
532 tz = x(iz)-x(jz) ! z1 - z2
533! The first derivatives of tx, ty, and tz w.r.t. the x variables are +1 or -1
534! The second derivatives of tx, ty, and tz are zero
535 dist = tx**2 + ty**2 + tz**2
536! The first derivatives of dist are
537! d(dist)/dx = d(dist)/d(tx)*d(tx)/dx = 2*tx*(+/-) (+1 for x1 and -1 for x2)
538! and similarly for d(dist)/dy = 2*ty*(+/-1) and d(dist)/dz = 2*tz*(+/-1)
539! The second derivatives of dist are
540! d2(dist)/dxidxj = 2 if xi=xj and 0 otherwise
541! d2(dist)/dyidyj = 2 if yi=yj and 0 otherwise
542! d2(dist)/dzidzj = 2 if zi=zj and 0 otherwise
543! All cross 2nd derivatives dxdy, dxdz, and dydz are zero
544!
545 distsq = 1/sqrt(dist) ! = dist**(-0.5)
546 dist3 = distsq**3
547 dist5 = distsq**5
548! The first derivatives of distsq are
549! d(distsq)/dx = -0.5*dist**(-1.5)*d(dist)/dx = -dist**(-1.5)*tx*(+/-1) = -distsq**3*tx*(+/-1)
550! d(distsq)/dy = -0.5*dist**(-1.5)*d(dist)/dy = -dist**(-1.5)*ty*(+/-1) = -distsq**3*ty*(+/-1)
551! d(distsq)/dz = -0.5*dist**(-1.5)*d(dist)/dz = -dist**(-1.5)*tz*(+/-1) = -distsq**3*tz*(+/-1)
552! The second derivatives of distsq are
553! d2(distsq)/dxidxj = -1.5*dist**(-2.5)*d(dist)/dxj*tx*(+/-1) - dist**(-1.5)*d(tx)/dxj*(+/-1)
554! = -1.5*distsq**5*2*tx*tx*(+/-1) - distsq**3*(+/-1)
555! d2(distsq)/dxidyj = -1.5*dist**(-2.5)*d(dist)/dyj*tx*(+/-1) - dist**(-1.5)*d(tx)/dyj*(+/-1)
556! = -1.5*distsq**5*2*ty*tx*(+/-1)
557 k = pos(ix,ix)
558 hsvl(k) = hsvl(k) + 3.0d0*dist5*tx**2 - dist3
559 k = pos(jx,jx)
560 hsvl(k) = hsvl(k) + 3.0d0*dist5*tx**2 - dist3
561 k = pos(ix,jx)
562 hsvl(k) = hsvl(k) - 3.0d0*dist5*tx**2 + dist3
563 k = pos(iy,iy)
564 hsvl(k) = hsvl(k) + 3.0d0*dist5*ty**2 - dist3
565 k = pos(jy,jy)
566 hsvl(k) = hsvl(k) + 3.0d0*dist5*ty**2 - dist3
567 k = pos(iy,jy)
568 hsvl(k) = hsvl(k) - 3.0d0*dist5*ty**2 + dist3
569 k = pos(iz,iz)
570 hsvl(k) = hsvl(k) + 3.0d0*dist5*tz**2 - dist3
571 k = pos(jz,jz)
572 hsvl(k) = hsvl(k) + 3.0d0*dist5*tz**2 - dist3
573 k = pos(iz,jz)
574 hsvl(k) = hsvl(k) - 3.0d0*dist5*tz**2 + dist3
575!
576! Off-diagonal blocks
577!
578 k = pos(ix,iy)
579 hsvl(k) = hsvl(k) + 3.0d0*dist5*tx*ty
580 k = pos(ix,jy)
581 hsvl(k) = hsvl(k) - 3.0d0*dist5*tx*ty
582 k = pos(jx,iy)
583 hsvl(k) = hsvl(k) - 3.0d0*dist5*tx*ty
584 k = pos(jx,jy)
585 hsvl(k) = hsvl(k) + 3.0d0*dist5*tx*ty
586 k = pos(ix,iz)
587 hsvl(k) = hsvl(k) + 3.0d0*dist5*tx*tz
588 k = pos(ix,jz)
589 hsvl(k) = hsvl(k) - 3.0d0*dist5*tx*tz
590 k = pos(jx,iz)
591 hsvl(k) = hsvl(k) - 3.0d0*dist5*tx*tz
592 k = pos(jx,jz)
593 hsvl(k) = hsvl(k) + 3.0d0*dist5*tx*tz
594 k = pos(iy,iz)
595 hsvl(k) = hsvl(k) + 3.0d0*dist5*ty*tz
596 k = pos(iy,jz)
597 hsvl(k) = hsvl(k) - 3.0d0*dist5*ty*tz
598 k = pos(jy,iz)
599 hsvl(k) = hsvl(k) - 3.0d0*dist5*ty*tz
600 k = pos(jy,jz)
601 hsvl(k) = hsvl(k) + 3.0d0*dist5*ty*tz
602 enddo
603 enddo
604 endif
605
607
608 Contains
609
610 Integer function pos(i,j)
611 Integer, Intent(in) :: i, j
612 pos = 1+(i-1)*(2*numvar+2-i)/2 + (j-i) ! Hessian position for variable (j,i), j >= i
613 End function pos
614
615End Function elec_2dlagrval
integer function std_solution(xval, xmar, xbas, xsta, yval, ymar, ybas, ysta, n, m, usrmem)
Definition comdecl.f90:132
integer function std_status(modsta, solsta, iter, objval, usrmem)
Definition comdecl.f90:88
integer function std_message(smsg, dmsg, nmsg, llen, usrmem, msgv)
Definition comdecl.f90:205
integer function std_errmsg(rowno, colno, posno, msglen, usrmem, msg)
Definition comdecl.f90:248
integer function elec_2dlagrval(x, u, hsrw, hscl, hsvl, nodrv, numvar, numcon, numhess, usrmem)
Compute the Lagrangian of the Hessian.
Definition elec2.f90:460
integer function elec_2dlagrsize(nodrv, numvar, numcon, numhess, maxhess, usrmem)
Definition elec2.f90:412
integer function pos(i, j)
Definition elec2.f90:585
integer function elec_2dlagrstr(hsrw, hscl, nodrv, numvar, numcon, numhess, usrmem)
Specify the structure of the Lagrangian of the Hessian.
Definition elec2.f90:431
integer function elec_fdeval(x, g, jac, rowno, jcnm, mode, ignerr, errcnt, n, nz, thread, usrmem)
Compute nonlinear terms and non-constant Jacobian elements.
Definition elec.f90:277
integer function elec_readmatrix(lower, curr, upper, vsta, type, rhs, esta, colsta, rowno, value, nlflag, n, m, nz, usrmem)
Define information about the model.
Definition elec.f90:157
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_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_hessfac(cntvect, hessfac)
factor for Hessian density relative to Jacobian density HessFac.
Definition conopt.f90:858
integer(c_int) function coidef_threads(cntvect, threads)
number of threads allowed internally in CONOPT.
Definition conopt.f90:627
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_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
float rndx()
Defines a pseudo random number between 0 and 1.
Definition leastsq.c:22
program electron
Main program. A simple setup and call of CONOPT.
Definition mp_elec.f90:18
integer(c_int) function coidef_2dlagrsize(cntvect, coi_2dlagrsize)
Definition conopt.f90:1521
integer hcalls
Definition elec2.f90:68
subroutine flog(msg, code)
Definition comdeclp.f90:48
subroutine startup
Definition comdeclp.f90:31