@@ -280,27 +280,14 @@ subroutine set_status(me,istat,string,i,r)
280280 integer ,intent (in ),optional :: i ! ! an integer value to append
281281 real (wp),intent (in ),optional :: r ! ! a real value to append
282282
283- character (len= 256 ) :: numstr ! ! for number fo string conversion
284283 character (len= :),allocatable :: message ! ! the full message to log
285284 integer :: iostat ! ! write `iostat` code
286285
287286 message = trim (string)
288- if (present (i)) then
289- numstr = ' '
290- write (numstr,fmt=* ,iostat= iostat) i
291- if (iostat/= 0 ) numstr = ' ****'
292- message = message// ' ' // trim (adjustl (numstr))
293- end if
294- if (present (r)) then
295- numstr = ' '
296- write (numstr,fmt=* ,iostat= iostat) r
297- if (iostat/= 0 ) numstr = ' ****'
298- message = message// ' ' // trim (adjustl (numstr))
299- end if
287+ if (present (i)) message = message// ' ' // int2str(i)
288+ if (present (r)) message = message// ' ' // real2str(r)
300289
301- if (me% verbose) then
302- write (me% iunit,' (A)' ,iostat= iostat) message
303- end if
290+ if (me% verbose) write (me% iunit,' (A)' ,iostat= iostat) message
304291
305292 ! store in the class:
306293 me% istat = istat
@@ -309,6 +296,42 @@ subroutine set_status(me,istat,string,i,r)
309296 end subroutine set_status
310297! *****************************************************************************************
311298
299+ ! *****************************************************************************************
300+ ! >
301+ ! Convert an integer to a string. Works for up to 256 digits.
302+
303+ function int2str (i ) result(s)
304+ integer , intent (in ) :: i ! ! integer to convert
305+ character (len= :),allocatable :: s ! ! string result
306+ character (len= 256 ) :: tmp ! ! temp string
307+ integer :: iostat ! ! write `iostat` code
308+ write (tmp,fmt=* ,iostat= iostat) i
309+ if (iostat/= 0 ) then
310+ s = ' ****'
311+ else
312+ s = trim (adjustl (tmp))
313+ end if
314+ end function int2str
315+ ! *****************************************************************************************
316+
317+ ! *****************************************************************************************
318+ ! >
319+ ! Convert a real to a string. Works for up to 256 digits.
320+
321+ function real2str (r ) result(s)
322+ real (wp), intent (in ) :: r ! ! real to convert
323+ character (len= :),allocatable :: s ! ! string result
324+ character (len= 256 ) :: tmp ! ! temp string
325+ integer :: iostat ! ! write `iostat` code
326+ write (tmp,fmt=* ,iostat= iostat) r
327+ if (iostat/= 0 ) then
328+ s = ' ****'
329+ else
330+ s = trim (adjustl (tmp))
331+ end if
332+ end function real2str
333+ ! *****************************************************************************************
334+
312335! *****************************************************************************************
313336! >
314337! Return the status code and message from the [[nlesolver_type]] class.
@@ -330,6 +353,7 @@ end subroutine set_status
330353! * -13 -- Error: backtracking linesearch tau must be in range (0, 1)
331354! * -14 -- Error: must specify grad_sparse, irow, and icol for sparsity_mode > 1
332355! * -15 -- Error: irow and icol must be the same length
356+ ! * -16 -- Error: xlow > xupp
333357! * -999 -- Error: class has not been initialized
334358! * 0 -- Class successfully initialized in [[nlesolver_type:initialize]]
335359! * 1 -- Required accuracy achieved
@@ -448,14 +472,16 @@ subroutine initialize_nlesolver_variables(me,&
448472 ! ! At most `min(m,n)` vectors will be allocated.
449473 procedure (sparse_solver_func),optional :: custom_solver_sparse ! ! for `sparsity_mode=5`, this is the
450474 ! ! user-provided linear solver.
451- logical ,intent (in ),optional :: bounds_mode ! ! how to handle the `x` variable bounds:
475+ integer ,intent (in ),optional :: bounds_mode ! ! how to handle the `x` variable bounds:
452476 ! !
453477 ! ! * 0 = ignore bounds
454478 ! ! * 1 = use bounds (if specified) by adjusting the `x` vector
455479 ! ! at each step so that each individual `x` component is within
456480 ! ! the bounds
457- real (wp),dimension (n),intent (in ),optional :: xlow ! ! lower bounds for `x` (size is `n`). only used if `bounds_mode>0`.
458- real (wp),dimension (n),intent (in ),optional :: xupp ! ! upper bounds for `x` (size is `n`). only used if `bounds_mode>0`.
481+ real (wp),dimension (n),intent (in ),optional :: xlow ! ! lower bounds for `x` (size is `n`). only used if `bounds_mode>0` and
482+ ! ! both `xlow` and `xupp` are specified.
483+ real (wp),dimension (n),intent (in ),optional :: xupp ! ! upper bounds for `x` (size is `n`). only used if `bounds_mode>0` and
484+ ! ! both `xlow` and `xupp` are specified.
459485
460486 logical :: status_ok ! ! true if there were no errors
461487
@@ -473,6 +499,11 @@ subroutine initialize_nlesolver_variables(me,&
473499 ! optional:
474500
475501 if (present (bounds_mode) .and. present (xlow) .and. present (xupp)) then
502+ if (any (xlow> xupp)) then ! check for consistency
503+ status_ok = .false.
504+ call me% set_status(istat = - 16 , string = ' Error: xlow > xupp' )
505+ return
506+ end if
476507 me% bounds_mode = bounds_mode
477508 me% xupp = xupp
478509 me% xlow = xlow
@@ -962,7 +993,20 @@ subroutine adjust_x_for_bounds(me,x)
962993 class(nlesolver_type),intent (inout ) :: me
963994 real (wp),dimension (me% n),intent (inout ) :: x ! ! the `x` vector to adjust
964995
965- if (me% bounds_mode== 1 ) x = min (max (x,me% xlow),me% xupp)
996+ integer :: i ! ! counter
997+
998+ if (me% bounds_mode== 1 ) then
999+ ! x = min(max(x,me%xlow),me%xupp)
1000+ do i = 1 , me% n
1001+ if (x(i)<me% xlow(i)) then
1002+ x(i) = me% xlow(i)
1003+ if (me% verbose) write (me% iunit, ' (A)' ) ' x(' // int2str(i)// ' ) < xlow(i) : adjusting to lower bound'
1004+ else if (x(i)>me% xupp(i)) then
1005+ x(i) = me% xupp(i)
1006+ if (me% verbose) write (me% iunit, ' (A)' ) ' x(' // int2str(i)// ' ) > xupp(i) : adjusting to upper bound'
1007+ end if
1008+ end do
1009+ end if
9661010
9671011 end subroutine adjust_x_for_bounds
9681012! *****************************************************************************************
0 commit comments