subroutine ch_cap ( ch ) !*****************************************************************************80 ! !! CH_CAP capitalizes a single character. ! ! Discussion: ! ! Instead of CHAR and ICHAR, we now use the ACHAR and IACHAR functions, ! which guarantee the ASCII collating sequence. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 19 July 1998 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input/output, character CH, the character to capitalize. ! implicit none character ch integer ( kind = 4 ) itemp itemp = iachar ( ch ) if ( 97 <= itemp .and. itemp <= 122 ) then ch = achar ( itemp - 32 ) end if return end subroutine file_name_inc ( file_name ) !*****************************************************************************80 ! !! FILE_NAME_INC increments a partially numeric filename. ! ! Discussion: ! ! It is assumed that the digits in the name, whether scattered or ! connected, represent a number that is to be increased by 1 on ! each call. If this number is all 9's on input, the output number ! is all 0's. Non-numeric letters of the name are unaffected. ! ! If the name is empty, then the routine stops. ! ! If the name contains no digits, the empty string is returned. ! ! Example: ! ! Input Output ! ----- ------ ! 'a7to11.txt' 'a7to12.txt' ! 'a7to99.txt' 'a8to00.txt' ! 'a9to99.txt' 'a0to00.txt' ! 'cat.txt' ' ' ! ' ' STOP! ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 September 2005 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input/output, character ( len = * ) FILE_NAME. ! On input, a character string to be incremented. ! On output, the incremented string. ! implicit none character c integer ( kind = 4 ) change integer ( kind = 4 ) digit character ( len = * ) file_name integer ( kind = 4 ) i integer ( kind = 4 ) lens lens = len_trim ( file_name ) if ( lens <= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'FILE_NAME_INC - Fatal error!' write ( *, '(a)' ) ' The input string is empty.' stop end if change = 0 do i = lens, 1, -1 c = file_name(i:i) if ( lge ( c, '0' ) .and. lle ( c, '9' ) ) then change = change + 1 digit = ichar ( c ) - 48 digit = digit + 1 if ( digit == 10 ) then digit = 0 end if c = char ( digit + 48 ) file_name(i:i) = c if ( c /= '0' ) then return end if end if end do if ( change == 0 ) then file_name = ' ' return end if return end subroutine get_unit ( iunit ) !*****************************************************************************80 ! !! GET_UNIT returns a free FORTRAN unit number. ! ! Discussion: ! ! A "free" FORTRAN unit number is an integer between 1 and 99 which ! is not currently associated with an I/O device. A free FORTRAN unit ! number is needed in order to open a file with the OPEN command. ! ! If IUNIT = 0, then no free FORTRAN unit could be found, although ! all 99 units were checked (except for units 5, 6 and 9, which ! are commonly reserved for console I/O). ! ! Otherwise, IUNIT is an integer between 1 and 99, representing a ! free FORTRAN unit. Note that GET_UNIT assumes that units 5 and 6 ! are special, and will never return those values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 18 September 2005 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) IUNIT, the free unit number. ! implicit none integer ( kind = 4 ) i integer ( kind = 4 ) ios integer ( kind = 4 ) iunit logical lopen iunit = 0 do i = 1, 99 if ( i /= 5 .and. i /= 6 .and. i /= 9 ) then inquire ( unit = i, opened = lopen, iostat = ios ) if ( ios == 0 ) then if ( .not. lopen ) then iunit = i return end if end if end if end do return end subroutine p00_fun ( problem, option, nvar, x, fx ) !*****************************************************************************80 ! !! P00_FUN evaluates the function for any problem. ! ! Discussion: ! ! These problems were collected by Professor Werner Rheinboldt, of the ! University of Pittsburgh, and were used in the development of the ! PITCON program. ! ! Index: ! ! 1 The Freudenstein-Roth function ! 2 The Boggs function ! 3 The Powell function ! 4 The Broyden function ! 5 The Wacker function ! 6 The Aircraft stability function ! 7 The Cell kinetic function ! 8 The Riks mechanical problem ! 9 The Oden mechanical problem ! 10 Torsion of a square rod, finite difference solution ! 11 Torsion of a square rod, finite element solution ! 12 The materially nonlinear problem ! 13 Simpson's mildly nonlinear boundary value problem ! 14 Keller's boundary value problem ! 15 The Trigger Circuit ! 16 The Moore-Spence Chemical Reaction Integral Equation ! 17 The Bremermann Propane Combustion System ! 18 The semiconductor problem ! 19 The nitric acid absorption flash ! 20 The buckling spring ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Rami Melhem, Werner Rheinboldt, ! A Comparison of Methods for Determining Turning Points of ! Nonlinear Equations, ! Computing, ! Volume 29, Number 3, September 1982, pages 201-226. ! ! Werner Rheinboldt, ! Numerical Analysis of Parameterized Nonlinear Equations, ! Wiley, 1986, ! ISBN: 0-471-88814-1, ! LC: QA372.R54. ! ! Werner Rheinboldt, ! Sample Problems for Continuation Processes, ! Technical Report ICMA-80-?, ! Institute for Computational Mathematics and Applications, ! Department of Mathematics, ! University of Pittsburgh, November 1980. ! ! Werner Rheinboldt, John Burkardt, ! A Locally Parameterized Continuation Process, ! ACM Transactions on Mathematical Software, ! Volume 9, Number 2, June 1983, pages 215-235. ! ! Werner Rheinboldt, John Burkardt, ! Algorithm 596: ! A Program for a Locally Parameterized ! Continuation Process, ! ACM Transactions on Mathematical Software, ! Volume 9, Number 2, June 1983, pages 236-241. ! ! Werner Rheinboldt, ! Computation of Critical Boundaries on Equilibrium Manifolds, ! SIAM Journal on Numerical Analysis, ! Volume 19, Number 3, June 1982, pages 653-669. ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) option integer ( kind = 4 ) problem real ( kind = 8 ) x(nvar) if ( problem == 1 ) then call p01_fun ( option, nvar, x, fx ) else if ( problem == 2 ) then call p02_fun ( option, nvar, x, fx ) else if ( problem == 3 ) then call p03_fun ( option, nvar, x, fx ) else if ( problem == 4 ) then call p04_fun ( option, nvar, x, fx ) else if ( problem == 5 ) then call p05_fun ( option, nvar, x, fx ) else if ( problem == 6 ) then call p06_fun ( option, nvar, x, fx ) else if ( problem == 7 ) then call p07_fun ( option, nvar, x, fx ) else if ( problem == 8 ) then call p08_fun ( option, nvar, x, fx ) else if ( problem == 9 ) then call p09_fun ( option, nvar, x, fx ) else if ( problem == 10 ) then call p10_fun ( option, nvar, x, fx ) else if ( problem == 11 ) then call p11_fun ( option, nvar, x, fx ) else if ( problem == 12 ) then call p12_fun ( option, nvar, x, fx ) else if ( problem == 13 ) then call p13_fun ( option, nvar, x, fx ) else if ( problem == 14 ) then call p14_fun ( option, nvar, x, fx ) else if ( problem == 15 ) then call p15_fun ( option, nvar, x, fx ) else if ( problem == 16 ) then call p16_fun ( option, nvar, x, fx ) else if ( problem == 17 ) then call p17_fun ( option, nvar, x, fx ) else if ( problem == 18 ) then call p18_fun ( option, nvar, x, fx ) else if ( problem == 19 ) then call p19_fun ( option, nvar, x, fx ) else if ( problem == 20 ) then call p20_fun ( option, nvar, x, fx ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_FUN - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized problem number = ', problem stop end if return end subroutine p00_jac ( problem, option, nvar, x, jac ) !*****************************************************************************80 ! !! P00_JAC evaluates the jacobian for any problem. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) problem real ( kind = 8 ) x(nvar) if ( problem == 1 ) then call p01_jac ( option, nvar, x, jac ) else if ( problem == 2 ) then call p02_jac ( option, nvar, x, jac ) else if ( problem == 3 ) then call p03_jac ( option, nvar, x, jac ) else if ( problem == 4 ) then call p04_jac ( option, nvar, x, jac ) else if ( problem == 5 ) then call p05_jac ( option, nvar, x, jac ) else if ( problem == 6 ) then call p06_jac ( option, nvar, x, jac ) else if ( problem == 7 ) then call p07_jac ( option, nvar, x, jac ) else if ( problem == 8 ) then call p08_jac ( option, nvar, x, jac ) else if ( problem == 9 ) then call p09_jac ( option, nvar, x, jac ) else if ( problem == 10 ) then call p10_jac ( option, nvar, x, jac ) else if ( problem == 11 ) then call p11_jac ( option, nvar, x, jac ) else if ( problem == 12 ) then call p12_jac ( option, nvar, x, jac ) else if ( problem == 13 ) then call p13_jac ( option, nvar, x, jac ) else if ( problem == 14 ) then call p14_jac ( option, nvar, x, jac ) else if ( problem == 15 ) then call p15_jac ( option, nvar, x, jac ) else if ( problem == 16 ) then call p16_jac ( option, nvar, x, jac ) else if ( problem == 17 ) then call p17_jac ( option, nvar, x, jac ) else if ( problem == 18 ) then call p18_jac ( option, nvar, x, jac ) else if ( problem == 19 ) then call p19_jac ( option, nvar, x, jac ) else if ( problem == 20 ) then call p20_jac ( option, nvar, x, jac ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_JAC - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized problem number = ', problem stop end if ! ! Guarantee that the last row is zeroed out. ! jac(nvar,1:nvar) = 0.0D+00 return end subroutine p00_jac_check ( problem, option, nvar, x, max_adif, max_adif_i, & max_adif_j, max_rdif, max_rdif_i, max_rdif_j ) !*****************************************************************************80 ! !! P00_JAC_CHECK compares the jacobian with a finite difference estimate. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) MAX_ADIF, the maximum absolute difference. ! ! Output, integer ( kind = 4 ) MAX_ADIF_I, MAX_ADIF_J, the indices where ! the maximmum absolute difference was found. ! ! Output, real ( kind = 8 ) MAX_RDIF, the maximum relative difference. ! ! Output, integer ( kind = 4 ) MAX_RDIF_I, MAX_RDIF_J, the indices where ! the maximmum relative difference was found. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) dif integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) jac_dif(nvar,nvar) real ( kind = 8 ) max_adif integer ( kind = 4 ) max_adif_i integer ( kind = 4 ) max_adif_j real ( kind = 8 ) max_rdif integer ( kind = 4 ) max_rdif_i integer ( kind = 4 ) max_rdif_j integer ( kind = 4 ) problem real ( kind = 8 ), parameter :: rel = 0.0001D+00 real ( kind = 8 ) x(nvar) ! ! Compute the jacobian. ! call p00_jac ( problem, option, nvar, x, jac ) ! ! Estimate the jacobian via finite differences. ! call p00_jac_dif ( problem, option, nvar, x, jac_dif ) ! ! Compare the jacobians. ! max_rdif = 0.0D+00 max_rdif_i = 0 max_rdif_j = 0 max_adif = 0.0D+00 max_adif_i = 0 max_adif_j = 0 do i = 1, nvar - 1 do j = 1, nvar dif = abs ( jac(i,j) - jac_dif(i,j) ) if ( max_adif < dif ) then max_adif = dif max_adif_i = i max_adif_j = j end if if ( rel < abs ( jac(i,j) ) ) then if ( max_rdif * abs ( jac(i,j) ) < dif ) then max_rdif = dif / abs ( jac(i,j) ) max_rdif_i = i max_rdif_j = j end if end if end do end do return end subroutine p00_jac_dif ( problem, option, nvar, x, jac_dif ) !*****************************************************************************80 ! !! P00_JAC_DIF estimates the jacobian via finite differences. ! ! Discussion: ! ! This is a relatively unsophisticated way of estimating the jacobian. ! The value of the internal parameter REL, set below, can affect ! the results in a strong way. If the jacobian reported by this ! routine seems unsatisfactory, check the results for values of ! REL that are 10 times larger and smaller, and see if the trend ! makes sense. Values of REL that are too large for a given ! problem will make crude estimates, but values that are too small ! will result in roundoff, and in severe cases, the computation of ! zeroes in the jacobian. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 21 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC_DIF(NVAR,NVAR), an estimate of the jacobian. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) dx real ( kind = 8 ) fxm(nvar) real ( kind = 8 ) fxp(nvar) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac_dif(nvar,nvar) integer ( kind = 4 ) problem real ( kind = 8 ), parameter :: REL = 0.0001D+00 real ( kind = 8 ) x(nvar) real ( kind = 8 ) xsave ! ! Perturb each variable. ! do j = 1, nvar ! ! Save X(J), and compute a perturbation. ! xsave = x(j) dx = REL * ( abs ( xsave ) + 1.0D+00 ) ! ! Compute the function value at X + dX. ! x(j) = xsave + dx call p00_fun ( problem, option, nvar, x, fxp ) ! ! Compute the function value at X - dX. ! x(j) = xsave - dx call p00_fun ( problem, option, nvar, x, fxm ) ! ! Restore X(J). ! x(j) = xsave ! ! Compute column J of the finite difference jacobian. ! do i = 1, nvar - 1 jac_dif(i,j) = 0.5D+00 * ( fxp(i) - fxm(i) ) / dx end do end do return end subroutine p00_limit ( problem, option, nvar, x1, tan1, x2, tan2, lim, & x, tan, status ) !*****************************************************************************80 ! !! P00_LIMIT seeks a limit point. ! ! Discussion: ! ! For a given index 1 <= LIM <= NVAR, a limit point X is a point which ! satisfies F(X) = 0 and TAN(X)(LIM) = 0, that is, X is a point on the ! solution curve, and the LIM-th component of the tangent vector at X ! is zero. ! ! This function may be called if a limit point has been bracketed, ! that is, if X1 and X2 are points on the curve with the property that ! there is a change in sign in the LIM-th component of the tangent ! vector between X1 and X2. ! ! The function carries out an iteration seeking a point X between ! X1 and X2 for which the LIM-th tangent component is zero. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X1(NVAR), TAN1(NVAR), a point on the curve, ! and its tangent vector. ! ! Input, real ( kind = 8 ) X2(NVAR), TAN2(NVAR), a second point on the curve, ! and its tangent vector. ! ! Input, integer ( kind = 4 ) LIM, the index of the entry of TAN which ! we are seeking to zero. ! ! Output, real ( kind = 8 ) X(NVAR), TAN(NVAR), the computed limit point ! and its tangent vector. ! ! Output, integer ( kind = 4 ) STATUS. ! nonnegative, the limit point was computed in STATUS steps. ! negative, the limit point could not be computed. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) a real ( kind = 8 ) arg real ( kind = 8 ) b integer ( kind = 4 ) lim integer ( kind = 4 ) option integer ( kind = 4 ) par_index integer ( kind = 4 ) problem integer ( kind = 4 ) status integer ( kind = 4 ) status_zero integer ( kind = 4 ) status_newton real ( kind = 8 ) tan(nvar) real ( kind = 8 ) tan1(nvar) real ( kind = 8 ) tan2(nvar) real ( kind = 8 ) tol real ( kind = 8 ) value logical, parameter :: VERBOSE = .false. real ( kind = 8 ) x(nvar) real ( kind = 8 ) x1(nvar) real ( kind = 8 ) x2(nvar) ! ! Use a fixed parameter index, but do NOT use LIM. ! x(1:nvar) = x2(1:nvar) - x1(1:nvar) x(lim) = 0.0D+00 call r8vec_amax_index ( nvar, x, par_index ) ! ! Start the zero finding process. ! a = 0.0D+00 b = 1.0D+00 tol = sqrt ( epsilon ( tol ) ) arg = 0.0D+00 status_zero = 0 value = 0.0D+00 status = 0 do call zero_rc ( a, b, tol, arg, status_zero, value ) if ( status_zero < 0 ) then status = -1 write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_LIMIT - Fatal error!' write ( *, '(a)' ) ' ZERO_RC returned an error flag!' exit end if if ( arg == 0.0D+00 ) then x(1:nvar) = x1(1:nvar) tan(1:nvar) = tan1(1:nvar) else if ( arg == 1.0D+00 ) then x(1:nvar) = x2(1:nvar) tan(1:nvar) = tan2(1:nvar) else x(1:nvar) = ( 1.0D+00 - arg ) * x1(1:nvar) & + arg * x2(1:nvar) call p00_newton ( problem, option, nvar, x, par_index, status_newton ) if ( status_newton < 0 ) then status = -2 write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_LIMIT - Fatal error!' write ( *, '(a)' ) ' ZERO_RC returned an error flag!' exit end if call p00_tan ( problem, option, nvar, x, tan ) end if value = tan(lim) if ( VERBOSE ) then write ( *, '(2x,i8,2x,g14.8,2x,g14.8)' ) status_zero, arg, value end if status = status + 1 if ( status_zero == 0 ) then exit end if end do return end subroutine p00_newton ( problem, option, nvar, x, par_index, status ) !*****************************************************************************80 ! !! P00_NEWTON applies Newton's method to an approximate root. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 06 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input/output, real ( kind = 8 ) X(NVAR). ! On input, the starting point of Newton's method. ! On output, an improved estimate of the root of F(X)=0, if the ! algorithm converged. ! ! Input, integer ( kind = 4 ) PAR_INDEX, the index of the parameter ! to be fixed. This variable should be between 1 and NVAR. However, ! the user can set it to 0, indicating that the program should make an ! intelligent choice for the index. ! ! Output, integer ( kind = 4 ) STATUS, the status of the iteration. ! -3, the full number of steps was taken without convergence. ! (however, the output X might be CLOSE to a good solution). ! -2, the iteration seemed to be diverging, and was halted. ! -1, the jacobian was singular, and the iteration was halted. ! nonnegative, the convergence test was satisfied, and this is the ! number of steps taken (possibly 0). ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar) real ( kind = 8 ), parameter :: FX_ABS_TOL = 0.000001D+00 real ( kind = 8 ) fx_max real ( kind = 8 ) fx_max_init integer ( kind = 4 ) ipar integer ( kind = 4 ) ipivot(nvar) integer ( kind = 4 ) i integer ( kind = 4 ) info integer ( kind = 4 ) option integer ( kind = 4 ) it integer ( kind = 4 ), parameter :: IT_MAX = 20 integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) job integer ( kind = 4 ) par_index real ( kind = 8 ) par_value integer ( kind = 4 ) problem integer ( kind = 4 ) status logical, parameter :: VERBOSE = .false. real ( kind = 8 ) x(nvar) if ( par_index < 1 .or. nvar < par_index ) then call p00_par_index ( problem, option, nvar, x, par_index ) if ( VERBOSE ) then write ( *, '(a)' ) ' ' write ( *, '(a,i8,a)' ) & ' Iteration will hold index ', par_index, ' fixed.' end if end if par_value = x(par_index) if ( VERBOSE ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_NEWTON' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' Step F(X)' write ( *, '(a)' ) ' ' end if do it = 0, IT_MAX ! ! Compute the function value. ! call p00_fun ( problem, option, nvar, x, fx ) fx(nvar) = x(par_index) - par_value ! ! Compute the norm of the function value. ! fx_max = maxval ( abs ( fx(1:nvar) ) ) if ( VERBOSE ) then write ( *, '(2x,i8,2x,g14.6)' ) it, fx_max end if if ( it == 0 ) then fx_max_init = fx_max end if ! ! If the function norm is small enough, return. ! if ( abs ( fx_max ) < FX_ABS_TOL ) then status = it exit end if ! ! If the function norm seems to be exploding, halt. ! if ( 1000.0 * fx_max_init < abs ( fx_max ) ) then status = -2 exit end if if ( it == IT_MAX ) then status = -3 exit end if ! ! Compute the jacobian. ! call p00_jac ( problem, option, nvar, x, jac ) jac(nvar,1:nvar) = 0.0D+00 jac(nvar,par_index) = 1.0D+00 ! ! Factor the jacobian. ! call sge_fa ( nvar, nvar, jac, ipivot, info ) if ( info /= 0 ) then status = -1 exit end if ! ! Solve the system JAC * DX = FX ! job = 0 call sge_sl ( nvar, nvar, jac, ipivot, fx, job ) ! ! Update X = X - DX. ! x(1:nvar) = x(1:nvar) - fx(1:nvar) end do return end subroutine p00_nvar ( problem, option, nvar ) !*****************************************************************************80 ! !! P00_NVAR sets the number of variables for any problem. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) problem integer ( kind = 4 ) nvar if ( problem == 1 ) then call p01_nvar ( option, nvar ) else if ( problem == 2 ) then call p02_nvar ( option, nvar ) else if ( problem == 3 ) then call p03_nvar ( option, nvar ) else if ( problem == 4 ) then call p04_nvar ( option, nvar ) else if ( problem == 5 ) then call p05_nvar ( option, nvar ) else if ( problem == 6 ) then call p06_nvar ( option, nvar ) else if ( problem == 7 ) then call p07_nvar ( option, nvar ) else if ( problem == 8 ) then call p08_nvar ( option, nvar ) else if ( problem == 9 ) then call p09_nvar ( option, nvar ) else if ( problem == 10 ) then call p10_nvar ( option, nvar ) else if ( problem == 11 ) then call p11_nvar ( option, nvar ) else if ( problem == 12 ) then call p12_nvar ( option, nvar ) else if ( problem == 13 ) then call p13_nvar ( option, nvar ) else if ( problem == 14 ) then call p14_nvar ( option, nvar ) else if ( problem == 15 ) then call p15_nvar ( option, nvar ) else if ( problem == 16 ) then call p16_nvar ( option, nvar ) else if ( problem == 17 ) then call p17_nvar ( option, nvar ) else if ( problem == 18 ) then call p18_nvar ( option, nvar ) else if ( problem == 19 ) then call p19_nvar ( option, nvar ) else if ( problem == 20 ) then call p20_nvar ( option, nvar ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_NVAR - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized problem index = ', problem stop end if return end subroutine p00_option_num ( problem, option_num ) !*****************************************************************************80 ! !! P00_OPTION_NUM returns the number of options available for a problem. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options available ! for this problem. OPTION_NUM is always at least 1. ! implicit none integer ( kind = 4 ) option_num integer ( kind = 4 ) problem if ( problem == 1 ) then call p01_option_num ( option_num ) else if ( problem == 2 ) then call p02_option_num ( option_num ) else if ( problem == 3 ) then call p03_option_num ( option_num ) else if ( problem == 4 ) then call p04_option_num ( option_num ) else if ( problem == 5 ) then call p05_option_num ( option_num ) else if ( problem == 6 ) then call p06_option_num ( option_num ) else if ( problem == 7 ) then call p07_option_num ( option_num ) else if ( problem == 8 ) then call p08_option_num ( option_num ) else if ( problem == 9 ) then call p09_option_num ( option_num ) else if ( problem == 10 ) then call p10_option_num ( option_num ) else if ( problem == 11 ) then call p11_option_num ( option_num ) else if ( problem == 12 ) then call p12_option_num ( option_num ) else if ( problem == 13 ) then call p13_option_num ( option_num ) else if ( problem == 14 ) then call p14_option_num ( option_num ) else if ( problem == 15 ) then call p15_option_num ( option_num ) else if ( problem == 16 ) then call p16_option_num ( option_num ) else if ( problem == 17 ) then call p17_option_num ( option_num ) else if ( problem == 18 ) then call p18_option_num ( option_num ) else if ( problem == 19 ) then call p19_option_num ( option_num ) else if ( problem == 20 ) then call p20_option_num ( option_num ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_OPTION_NUM - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized problem index = ', problem stop end if return end subroutine p00_par_index ( problem, option, nvar, x, par_index ) !*****************************************************************************80 ! !! P00_PAR_INDEX chooses the index of the continuation parameter. ! ! Discussion: ! ! Given the NVAR-dimensional point X, the (NVAR-1)-dimensional function ! F(X), and the NVAR-1 by NVAR jacobian matrix, let the NVAR-dimensional ! vector TAN be any null vector of JAC. ! ! JAC * TAN = 0 ! ! Choose PAR_INDEX to be the index of TAN of maximum absolute value. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 29 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real X(NVAR), the starting point of Newton's method. ! ! Output, integer ( kind = 4 ) PAR_INDEX, the index of the parameter ! to be held fixed. This variable will be between 1 and NVAR. It is ! the index of the variable which is currently changing most rapidly ! along the curve F(X) = 0. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option integer ( kind = 4 ) par_index integer ( kind = 4 ) problem real ( kind = 8 ) tan(nvar) real ( kind = 8 ) x(nvar) call p00_tan ( problem, option, nvar, x, tan ) call r8vec_amax_index ( nvar, tan, par_index ) return end subroutine p00_problem_num ( problem_num ) !*****************************************************************************80 ! !! P00_PROBLEM_NUM returns the number of problems available. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 28 August 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) PROBLEM_NUM, the number of problems. ! implicit none integer ( kind = 4 ) problem_num problem_num = 20 return end subroutine p00_start ( problem, option, nvar, x ) !*****************************************************************************80 ! !! P00_START returns a starting point for any problem. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option integer ( kind = 4 ) problem real ( kind = 8 ) x(nvar) if ( problem == 1 ) then call p01_start ( option, nvar, x ) else if ( problem == 2 ) then call p02_start ( option, nvar, x ) else if ( problem == 3 ) then call p03_start ( option, nvar, x ) else if ( problem == 4 ) then call p04_start ( option, nvar, x ) else if ( problem == 5 ) then call p05_start ( option, nvar, x ) else if ( problem == 6 ) then call p06_start ( option, nvar, x ) else if ( problem == 7 ) then call p07_start ( option, nvar, x ) else if ( problem == 8 ) then call p08_start ( option, nvar, x ) else if ( problem == 9 ) then call p09_start ( option, nvar, x ) else if ( problem == 10 ) then call p10_start ( option, nvar, x ) else if ( problem == 11 ) then call p11_start ( option, nvar, x ) else if ( problem == 12 ) then call p12_start ( option, nvar, x ) else if ( problem == 13 ) then call p13_start ( option, nvar, x ) else if ( problem == 14 ) then call p14_start ( option, nvar, x ) else if ( problem == 15 ) then call p15_start ( option, nvar, x ) else if ( problem == 16 ) then call p16_start ( option, nvar, x ) else if ( problem == 17 ) then call p17_start ( option, nvar, x ) else if ( problem == 18 ) then call p18_start ( option, nvar, x ) else if ( problem == 19 ) then call p19_start ( option, nvar, x ) else if ( problem == 20 ) then call p20_start ( option, nvar, x ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_START - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized problem index = ', problem stop end if return end subroutine p00_step ( problem, option, nvar, x, par_index, h, hmin, hmax, & status ) !*****************************************************************************80 ! !! P00_STEP takes one continuation step. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 06 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real X(NVAR), the starting point. ! ! Input, integer ( kind = 4 ) PAR_INDEX, the continuation parameter. ! If the program is free to choose this value, set it to 0. ! ! Input, real H, HMIN, HMAX, the suggested step, and the minimum ! and maximum stepsizes. H may be negative. ! ! Output, real X(NVAR), the new point, if STATUS = 0. ! ! Output, real H, the stepsize that was used. ! ! Output, integer ( kind = 4 ) STATUS, the status of the calculation. ! 0, successful. ! nonzero, the Newton iteration failed repeatedly even when the ! minimum stepsize was used. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option integer ( kind = 4 ) par_index integer ( kind = 4 ) problem real ( kind = 8 ) r8_sign integer ( kind = 4 ) status real ( kind = 8 ) tan(nvar) real ( kind = 8 ) x(nvar) real ( kind = 8 ) xt(nvar) ! ! Compute the tangent. ! call p00_tan ( problem, option, nvar, x, tan ) ! ! Estimate the next point. ! do xt(1:nvar) = x(1:nvar) + h * tan(1:nvar) ! ! Use the Newton method. ! call p00_newton ( problem, option, nvar, xt, par_index, status ) if ( status == 0 ) then exit end if if ( abs ( h ) <= hmin ) then exit end if if ( hmin < abs ( h ) ) then h = r8_sign ( h ) * max ( abs ( h ) / 2.0D+00, hmin ) end if end do x(1:nvar) = xt(1:nvar) return end subroutine p00_stepsize ( problem, option, h, hmin, hmax ) !*****************************************************************************80 ! !! P00_STEPSIZE returns step sizes for any problem. ! ! Discussion: ! ! The routine returns a suggested initial stepsize, and suggestions for ! the minimum and maximum stepsizes. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option integer ( kind = 4 ) problem if ( problem == 1 ) then call p01_stepsize ( option, h, hmin, hmax ) else if ( problem == 2 ) then call p02_stepsize ( option, h, hmin, hmax ) else if ( problem == 3 ) then call p03_stepsize ( option, h, hmin, hmax ) else if ( problem == 4 ) then call p04_stepsize ( option, h, hmin, hmax ) else if ( problem == 5 ) then call p05_stepsize ( option, h, hmin, hmax ) else if ( problem == 6 ) then call p06_stepsize ( option, h, hmin, hmax ) else if ( problem == 7 ) then call p07_stepsize ( option, h, hmin, hmax ) else if ( problem == 8 ) then call p08_stepsize ( option, h, hmin, hmax ) else if ( problem == 9 ) then call p09_stepsize ( option, h, hmin, hmax ) else if ( problem == 10 ) then call p10_stepsize ( option, h, hmin, hmax ) else if ( problem == 11 ) then call p11_stepsize ( option, h, hmin, hmax ) else if ( problem == 12 ) then call p12_stepsize ( option, h, hmin, hmax ) else if ( problem == 13 ) then call p13_stepsize ( option, h, hmin, hmax ) else if ( problem == 14 ) then call p14_stepsize ( option, h, hmin, hmax ) else if ( problem == 15 ) then call p15_stepsize ( option, h, hmin, hmax ) else if ( problem == 16 ) then call p16_stepsize ( option, h, hmin, hmax ) else if ( problem == 17 ) then call p17_stepsize ( option, h, hmin, hmax ) else if ( problem == 18 ) then call p18_stepsize ( option, h, hmin, hmax ) else if ( problem == 19 ) then call p19_stepsize ( option, h, hmin, hmax ) else if ( problem == 20 ) then call p20_stepsize ( option, h, hmin, hmax ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_STEPSIZE - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized problem number = ', problem stop end if return end subroutine p00_tan ( problem, option, nvar, x, tan ) !*****************************************************************************80 ! !! P00_TAN determines a tangent vector at X. ! ! Discussion: ! ! If X is a solution of F(Y) = 0, then the vector TAN ! is tangent to the curve of solutions at X. ! ! If X is not a solution of F(Y) = 0, then the vector TAN ! is tangent to the curve F(Y) = F(X) at X. ! ! The vector will have unit euclidean norm. ! ! The sign of TAN will be chosen so that the determinant ! of F'(X) augmented with a final row equal to TAN will be positive. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the evaluation point. ! ! Output, real ( kind = 8 ) TAN(NVAR), a tangent vector at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) jac_det real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ), allocatable, dimension ( :, : ) :: nullspace integer ( kind = 4 ) nullspace_size integer ( kind = 4 ) option integer ( kind = 4 ) problem real ( kind = 8 ) tan(nvar) real ( kind = 8 ) tan_norm real ( kind = 8 ) x(nvar) ! ! Compute the jacobian. ! call p00_jac ( problem, option, nvar, x, jac ) ! ! Compute the nullspace size. ! call r8mat_nullspace_size ( nvar, nvar, jac, nullspace_size ) if ( nullspace_size < 1 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_TAN - Fatal error!' write ( *, '(a)' ) ' The matrix seems to have no nullspace.' write ( *, '(a)' ) ' The tangent vector could not be computed.' stop end if ! ! Compute the nullspace. ! allocate ( nullspace(1:nvar,1:nullspace_size) ) call r8mat_nullspace ( nvar, nvar, jac, nullspace_size, nullspace ) tan(1:nvar) = nullspace(1:nvar,1) deallocate ( nullspace ) ! ! Choose the sign of TAN by the determinant condition. ! jac(nvar,1:nvar) = tan(1:nvar) call r8mat_det ( nvar, jac, jac_det ) if ( jac_det < 0.0D+00 ) then tan(1:nvar) = - tan(1:nvar) end if tan_norm = sqrt ( sum ( tan(1:nvar)**2 ) ) tan(1:nvar) = tan(1:nvar) / tan_norm return end subroutine p00_target ( problem, option, nvar, x1, x2, tar_index, tar_value, & x, status ) !*****************************************************************************80 ! !! P00_TARGET computes a solution with a given component value. ! ! Discussion: ! ! If we write G(X) = X(TAR_INDEX) - TAR_VALUE, then we are seeking a ! solution of ! ! ( F(X) ) = ( 0 ) ! ( G(X) ) ( 0 ) ! ! We treat the index TAR_INDEX as the parameter to be held fixed. ! ! Typically, this routine would be called when the user has computed ! two successive solutions X1 and X2, with the property that the ! ! X1(TAR_INDEX) < TAR_VALUE < X2(TAR_INDEX) ! ! or vice-versa. ! ! In that case, the appropriate estimate for the starting point X is ! ! X = ( ( X2(TAR_INDEX) - TAR_VALUE ) * X1 ! + ( TAR_VALUE - X1(TAR_INDEX) ) * X2 ) ! / ( X2(TAR_INDEX) - X1(TAR_INDEX) ) ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 08 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X1(NVAR), X2(NVAR), two points satisying F(X) = 0. ! It is assumed that X1(TAR_INDEX) and X2(TAR_INDEX) bracket the ! desired value TAR_VALUE. ! ! Input, integer ( kind = 4 ) TAR_INDEX, the index of the entry of X whose ! value is being specified. ! ! Input, real ( kind = 8 ) TAR_VALUE, the desired value of X(TAR_INDEX). ! ! Output, integer ( kind = 4 ) STATUS. ! nonnegative, the target point was computed. ! negative, the target point could not be computed. ! ! Output, real ( kind = 8 ) X(NVAR), a point satisfying F(X) = 0 and ! X(TAR_INDEX)=TAR_VALUE. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option integer ( kind = 4 ) par_index integer ( kind = 4 ) problem integer ( kind = 4 ) status integer ( kind = 4 ) tar_index real ( kind = 8 ) tar_value real ( kind = 8 ) x(nvar) real ( kind = 8 ) x1(nvar) real ( kind = 8 ) x2(nvar) x(1:nvar) = ( ( x2(tar_index) - tar_value ) * x1(1:nvar) & + ( tar_value - x1(tar_index) ) * x2(1:nvar) ) & / ( x2(tar_index) - x1(tar_index) ); par_index = tar_index call p00_newton ( problem, option, nvar, x, par_index, status ) return end subroutine p00_title ( problem, option, title ) !*****************************************************************************80 ! !! P00_TITLE sets the title for any problem. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) PROBLEM, the problem index. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) problem character ( len = * ) title if ( problem == 1 ) then call p01_title ( option, title ) else if ( problem == 2 ) then call p02_title ( option, title ) else if ( problem == 3 ) then call p03_title ( option, title ) else if ( problem == 4 ) then call p04_title ( option, title ) else if ( problem == 5 ) then call p05_title ( option, title ) else if ( problem == 6 ) then call p06_title ( option, title ) else if ( problem == 7 ) then call p07_title ( option, title ) else if ( problem == 8 ) then call p08_title ( option, title ) else if ( problem == 9 ) then call p09_title ( option, title ) else if ( problem == 10 ) then call p10_title ( option, title ) else if ( problem == 11 ) then call p11_title ( option, title ) else if ( problem == 12 ) then call p12_title ( option, title ) else if ( problem == 13 ) then call p13_title ( option, title ) else if ( problem == 14 ) then call p14_title ( option, title ) else if ( problem == 15 ) then call p15_title ( option, title ) else if ( problem == 16 ) then call p16_title ( option, title ) else if ( problem == 17 ) then call p17_title ( option, title ) else if ( problem == 18 ) then call p18_title ( option, title ) else if ( problem == 19 ) then call p19_title ( option, title ) else if ( problem == 20 ) then call p20_title ( option, title ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P00_TITLE - Fatal error!' write ( *, '(a)' ) ' Unrecognized problem index = ', problem stop end if return end subroutine p01_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P01_FUN evaluates the function for problem 1. ! ! Title: ! ! The Freudenstein-Roth function ! ! Description: ! ! One way to use a continuation code as a nonlinear root finder ! is to start with a set of nonlinear equations G(X), and an ! approximate root A, and create a "homotopy" function F(X,Y) ! with the properties that F(A,0.0) = 0 and F(X,1.0) = G(X). ! Thus, the homotopy function F has a known exact solution ! from which we can start with no difficulty. If the continuation ! code can take us from Y = 0 to Y = 1, then we have found ! an X so that F(X,1.0) = 0, so we have found a solution to G(X)=0. ! ! The Freudenstein-Roth function F(X) is derived in this way ! from a homotopy of G(X): ! ! F ( X(1), X(2), X(3) ) = ! G ( X(1), X(2) ) - ( 1 - X(3) ) * G ( Y1, Y2 ) ! ! where Y1 and Y2 are some fixed values, and ! ! G(1) = X(1) - X(2)*X(2)*X(2) + 5*X(2)*X(2) - 2*X(2) - 13 ! G(2) = X(1) + X(2)*X(2)*X(2) + X(2)*X(2) - 14*X(2) - 29 ! ! Options 1, 2, 3: ! ! The starting point is X0 = ( 15, -2, 0 ). ! ! A great deal of information is available about the homotopy curve ! generated by this starting point: ! ! The function F(X) has the form ! ! F(1) = X(1) - X(2)**3 + 5*X(2)**2 - 2*X(2) - 13 + 34*(X(3)-1) ! F(2) = X(1) + X(2)**3 + X(2)**2 - 14*X(2) - 29 + 10*(X(3)-1) ! ! There is a closed form representation of the curve in terms of the ! second parameter: ! ! X(1) = (-11*X(2)**3 + 4*X(2)**2 + 114*X(2) + 214) / 6 ! X(2) = X(2) ! X(3) = ( X(2)**3 - 2*X(2)**2 - 6*X(2) + 4) / 12 ! ! The first option simply requests the production of solution points ! along the curve until a point is reached whose third component is ! exactly 1. ! ! Options 2 and 3 use the same starting point, and also stop when the ! third component is 1. However, these options in addition search ! for limit points in the first and third components of the solution, ! respectively. ! ! The target solution has X(3) = 1, and is ( 5, 4, 1 ). ! ! Limit points for X1: ! ! ( 14.28309, -1.741377, 0.2585779 ) ! ( 61.66936, 1.983801, -0.6638797 ) ! ! Limit points for X3: ! ! (20.48586, -0.8968053, 0.5875873) ! (61.02031, 2.230139, -0.6863528) ! ! The curve has several dramatic bends. ! ! ! Options 4, 5, and 6: ! ! The starting point is (4, 3, 0). ! ! The function F(X) has the form ! ! F(1) = X(1) - X(2)**3 + 5*X(2)**2 - 2*X(2) - 13 + 3*(X(3)-1) ! F(2) = X(1) + X(2)**3 + X(2)**2 - 14*X(2) - 29 - 31*(X(3)-1) ! ! There is a closed form representation of the curve in terms of the ! second parameter: ! ! X(1) = (14*X(2)**3 -79*X(2)**2 +52*X(2) + 245) / 17 ! X(2) = X(2) ! X(3) = ( X(2)**3 - 2*X(2)**2 - 6*X(2) + 9) / 17 ! ! The correct value of the solution at X(3)=1 is: ! ! (5, 4, 1) ! ! In option 5, limit points in the first component are sought, ! and in option 6, limit points in the third component are ! sought. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Ferdinand Freudenstein, Bernhard Roth, ! Numerical Solutions of Nonlinear Equations, ! Journal of the Association for Computing Machinery, ! Volume 10, 1963, Pages 550-556. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) gx(2) real ( kind = 8 ) gy(2) integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) ! ! Get the starting point, Y. ! call p01_start ( option, nvar, y ) ! ! G is the function value at the starting point, ! F the function value at the current point. ! call p01_gx ( y, gy ) call p01_gx ( x, gx ) ! ! The parameter X3 generates the homotopy curve. ! fx(1:nvar-1) = gx(1:nvar-1) + ( x(3) - 1.0D+00 ) * gy(1:nvar-1) return end subroutine p01_gx ( x, g ) !*****************************************************************************80 ! !! P01_GX evaluates the underlying function for problem 1. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 December 1998 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) X(2), the point at which the function is to ! be evaluated. ! ! Output, real ( kind = 8 ) G(2), the value of the function at X. ! implicit none real ( kind = 8 ) g(2) real ( kind = 8 ) x(2) g(1) = x(1) - ( ( x(2) - 5.0D+00 ) * x(2) + 2.0D+00 ) * x(2) - 13.0D+00 g(2) = x(1) + ( ( x(2) + 1.0D+00 ) * x(2) - 14.0D+00 ) * x(2) - 29.0D+00 return end subroutine p01_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P01_JAC evaluates the jacobian for problem 1. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) gy(3) integer ( kind = 4 ) option real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) jac(1:nvar,1:nvar) = 0.0D+00 jac(1,1) = 1.0D+00 jac(2,1) = 1.0D+00 jac(1,2) = ( - 3.0D+00 * x(2) + 10.0D+00 ) * x(2) - 2.0D+00 jac(2,2) = ( 3.0D+00 * x(2) + 2.0D+00 ) * x(2) - 14.0D+00 ! ! Get the starting point ! call p01_start ( option, nvar, y ) ! ! Get the function value at the starting point ! call p01_gx ( y, gy ) jac(1,3) = gy(1) jac(2,3) = gy(2) return end subroutine p01_nvar ( option, nvar ) !*****************************************************************************80 ! !! P01_NVAR sets the number of variables for problem 1. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option chosen for this problem. ! For some problems, several options are available. At least, ! OPTION = 1 is always legal. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 3 return end subroutine p01_option_num ( option_num ) !*****************************************************************************80 ! !! P01_OPTION_NUM returns the number of options for problem 1. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 6 return end subroutine p01_start ( option, nvar, x ) !*****************************************************************************80 ! !! P01_START returns a starting point for problem 1. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) if ( option == 1 .or. option == 2 .or. option == 3 ) then x(1:3) = (/ 15.0D+00, -2.0D+00, 0.0D+00 /) else if ( option == 4 .or. option == 5 .or. option == 6 ) then x(1:3) = (/ 4.0D+00, 3.0D+00, 0.0D+00 /) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P01_START - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p01_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P01_STEPSIZE returns step sizes for problem 1. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.30000D+00 hmin = 0.03125D+00 hmax = 4.00000D+00 return end subroutine p01_title ( option, title ) !*****************************************************************************80 ! !! P01_TITLE sets the title for problem 1. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Freudenstein-Roth function, (15,-2,0).' else if ( option == 2 ) then title = 'Freudenstein-Roth function, (15,-2,0), x1 limits.' else if ( option == 3 ) then title = 'Freudenstein-Roth function, (15,-2,0), x3 limits.' else if ( option == 4 ) then title = 'Freudenstein-Roth function, (4,3,0).' else if ( option == 5 ) then title = 'Freudenstein-Roth function, (4,3,0), x1 limits.' else if ( option == 6 ) then title = 'Freudenstein-Roth function, (4,3,0), x3 limits.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P01_TITLE - Fatal error!' write ( *, '(a)' ) ' Unrecognized option number.' stop end if return end subroutine p02_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P02_FUN evaluates the function for problem 2. ! ! Title: ! ! The Boggs function ! ! Description: ! ! The function F is derived via homotopy from a simpler function: ! ! F(X(1),X(2),X(3)) = G(X(1),X(2)) + (X(3)-1) * G(Y1,Y2) ! ! with ! ! (Y1, Y2) some starting value, ! ! and ! ! G(1) = X(1)*X(1) - X(2) + 1 ! G(2) = X(1) - COS(PI*X(2)/2) ! ! Options: ! ! OPTION = 1, ! use starting point ( 1, 0, 0 ). ! OPTION = 2, ! use starting point ( 1, -1, 0 ). ! OPTION = 3, ! use starting point ( 10, 10, 0 ). ! ! Target Points: ! ! For the target value X(3) = 1.0, the solution is ( 0, 1, 1 ). ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Boggs, ! The Solution of Nonlinear Systems by A-stable Integration Techniques, ! SIAM Journal on Numerical Analysis, ! Volume 8, Number 4, December 1971, pages 767-785. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) gx(2) real ( kind = 8 ) gy(2) integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) ! ! Get the starting point ! call p02_start ( option, nvar, y ) ! ! Get the function value at the starting point and at the ! current point. ! call p02_gx ( y, gy ) call p02_gx ( x, gx ) ! ! Use X3 to compute a homotopy. ! do i = 1, nvar - 1 fx(i) = gx(i) + ( x(3) - 1.0D+00 ) * gy(i) end do return end subroutine p02_gx ( x, g ) !*****************************************************************************80 ! !! P02_GX evaluates the underlying function for problem 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 December 1998 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) X(2), the point at which the function is to ! be evaluated. ! ! Output, real ( kind = 8 ) G(2), the value of the function at X. ! implicit none real ( kind = 8 ) g(2) real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 real ( kind = 8 ) x(2) g(1) = x(1) * x(1) - x(2) + 1.0D+00 g(2) = x(1) - cos ( pi * x(2) / 2.0D+00 ) return end subroutine p02_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P02_JAC evaluates the jacobian for problem 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) gy(2) integer ( kind = 4 ) option real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) jac(1:nvar,1:nvar) = 0.0D+00 jac(1,1) = 2.0D+00 * x(1) jac(2,1) = 1.0D+00 jac(1,2) = - 1.0D+00 jac(2,2) = 0.5D+00 * pi * sin ( 0.5D+00 * pi * x(2) ) ! ! Get the starting point ! call p02_start ( option, nvar, y ) ! ! Get the function value at the starting point ! call p02_gx ( y, gy ) jac(1,3) = gy(1) jac(2,3) = gy(2) return end subroutine p02_nvar ( option, nvar ) !*****************************************************************************80 ! !! P02_NVAR sets the number of variables for problem 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 3 return end subroutine p02_option_num ( option_num ) !*****************************************************************************80 ! !! P02_OPTION_NUM returns the number of options for problem 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 3 return end subroutine p02_start ( option, nvar, x ) !*****************************************************************************80 ! !! P02_START returns a starting point for problem 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) if ( option == 1 ) then x(1:3) = (/ 1.0D+00, 0.0D+00, 0.0D+00 /) else if ( option == 2 ) then x(1:3) = (/ 1.0D+00, -1.0D+00, 0.0D+00 /) else if ( option == 3 ) then x(1:3) = (/ 10.0D+00, 10.0D+00, 0.0D+00 /) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P02_START - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p02_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P02_STEPSIZE returns step sizes for problem 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.250D+00 hmin = 0.001D+00 hmax = 1.000D+00 return end subroutine p02_title ( option, title ) !*****************************************************************************80 ! !! P02_TITLE sets the title for problem 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Boggs function, (1,0,0).' else if ( option == 2 ) then title = 'Boggs function, (1,-1,0).' else if ( option == 3 ) then title = 'Boggs function, (10,10,0).' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P02_TITLE - Fatal error!' write ( *, '(a)' ) ' Unrecognized option number.' stop end if return end subroutine p03_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P03_FUN evaluates the function for problem 3. ! ! Title: ! ! The Powell function ! ! Description: ! ! The function F is derived via homotopy from a simpler function G: ! ! F(X(1),X(2),X(3)) = G(X(1),X(2)) + (X(3)-1)*G(Y1,Y2) ! ! with ! ! Y1, Y2 some starting point, ! ! and ! ! G(1) = 10000 * X(1) * X(2) - 1.0D+00 ! G(2) = exp ( -X(1) ) + exp ( -X(2) ) - 1.0001 ! ! Options: ! ! OPTION = 1, ! use starting point ( 3, 6, 0 ); ! OPTION = 2, ! use starting point ( 4, 5, 0 ); ! OPTION = 3, ! use starting point ( 6, 3, 0 ); ! OPTION = 4, ! use starting point ( 1, 1, 0 ). ! ! Special points: ! ! For all options, there is a solution with last component 1, whose ! value is either: ! ! (1.098159E-5, 9.106146, 1.0) ! or ! (9.106146, 1.098159E-5, 1.0) ! ! Comments: ! ! Note that the function G is symmetric in X(1) and X(2). Hence, ! the run with starting point (1,1,0) should be interesting! ! ! It would be worthwhile to seek limit points in X(3). ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Michael Powell, ! A FORTRAN Subroutine for Solving Systems of Nonlinear Algebraic Equations, ! in Numerical Methods for Nonlinear Algebraic Equations, ! Edited by Philip Rabinowitz, ! Gordon and Breach, 1970, ! ISBN13: 978-0677142302, ! LC: QA218.N85. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) gx(2) real ( kind = 8 ) gy(2) integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) ! ! Get the starting point ! call p03_start ( option, nvar, y ) ! ! Get the (underlying) function value at the starting point and at the ! current point. ! call p03_gx ( y, gy ) call p03_gx ( x, gx ) ! ! Use X3 to compute a homotopy. ! do i = 1, nvar - 1 fx(i) = gx(i) + ( x(3) - 1.0D+00 ) * gy(i) end do return end subroutine p03_gx ( x, g ) !*****************************************************************************80 ! !! P03_GX evaluates the underlying function for problem 3. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 19 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) X(2), the point at which the function is to ! be evaluated. ! ! Output, real ( kind = 8 ) G(2), the value of the function at X. ! implicit none real ( kind = 8 ) g(2) real ( kind = 8 ) x(2) g(1) = 10000.0D+00 * x(1) * x(2) - 1.0D+00 g(2) = exp ( - x(1) ) + exp ( - x(2) ) - 1.0001D+00 return end subroutine p03_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P03_JAC evaluates the jacobian for problem 3. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) gy(2) integer ( kind = 4 ) option real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) jac(1:nvar,1:nvar) = 0.0D+00 ! ! Get the starting point. ! call p03_start ( option, nvar, y ) ! ! Get the (underlying) function value at the starting point. ! call p03_gx ( y, gy ) ! ! The last column of the jacobian depends on the (underlying) function ! value at the starting point. ! jac(1,1) = 10000.0D+00 * x(2) jac(1,2) = 10000.0D+00 * x(1) jac(1,3) = gy(1) jac(2,1) = - exp ( - x(1) ) jac(2,2) = - exp ( - x(2) ) jac(2,3) = gy(2) return end subroutine p03_nvar ( option, nvar ) !*****************************************************************************80 ! !! P03_NVAR sets the number of variables for problem 3. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 3 return end subroutine p03_option_num ( option_num ) !*****************************************************************************80 ! !! P03_OPTION_NUM returns the number of options for problem 3. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 4 return end subroutine p03_start ( option, nvar, x ) !*****************************************************************************80 ! !! P03_START returns a starting point for problem 3. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) if ( option == 1 ) then x(1:3) = (/ 3.0D+00, 6.0D+00, 0.0D+00 /) else if ( option == 2 ) then x(1:3) = (/ 5.0D+00, 4.0D+00, 0.0D+00 /) else if ( option == 3 ) then x(1:3) = (/ 6.0D+00, 3.0D+00, 0.0D+00 /) else if ( option == 4 ) then x(1:3) = (/ 1.0D+00, 1.0D+00, 0.0D+00 /) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P03_START - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p03_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P03_STEPSIZE returns step sizes for problem 3. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.50000D+00 hmin = 0.00025D+00 hmax = 3.00000D+00 return end subroutine p03_title ( option, title ) !*****************************************************************************80 ! !! P03_TITLE sets the title for problem 3. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Powell function, (3,6,0).' else if ( option == 2 ) then title = 'Powell function, (4,5,0).' else if ( option == 3 ) then title = 'Powell function, (6,3,0).' else if ( option == 4 ) then title = 'Powell function, (1,1,0).' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P03_TITLE - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p04_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P04_FUN evaluates the function for problem 4. ! ! Title: ! ! The Broyden function ! ! Description: ! ! The function F is derived via homotopy from a simpler function G: ! ! F(X(1),X(2),X(3)) = g(X(1),X(2)) + (X(3)-1) * G(Y1,Y2). ! ! with ! ! (Y1,Y2) some starting point, ! ! and ! ! G(1) = 0.5*sin(X(1)*X(2)) - X(2)/PI - X(1) ! G(2) = (1-1/(4*PI))*(exp(2*X(1))-E) + E*X(2)/PI- 2*E*X(1) ! ! where "E" = exp(1). ! ! Options: ! ! The only option starts with (0.4, 3, 0), and seeks the target ! solution whose third component is 1. The correct value of the ! target solution is ! ! ( -0.2207014, 0.8207467, 1.0D+00 ) ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Charles Broyden, ! A New Method of Solving Nonlinear Simultaneous Equations, ! The Computer Journal, ! Volume 12, 1969, pages 94-99. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) gx(2) real ( kind = 8 ) gy(2) integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) ! ! Get the starting point. ! call p04_start ( option, nvar, y ) ! ! Get the function value at the starting point and at the ! current point. ! call p04_gx ( y, gy ) call p04_gx ( x, gx ) ! ! Use X3 to compute a homotopy. ! do i = 1, nvar - 1 fx(i) = gx(i) + ( x(3) - 1.0D+00 ) * gy(i) end do return end subroutine p04_gx ( x, g ) !*****************************************************************************80 ! !! P04_GX evaluates the underlying function for problem 4. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 December 1998 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) X(2), the point at which the function is to ! be evaluated. ! ! Output, real ( kind = 8 ) G(2), the value of the function at X. ! implicit none real ( kind = 8 ), parameter :: E = 2.71828182845904523536D+00 real ( kind = 8 ) g(2) real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 real ( kind = 8 ) x(2) g(1) = 0.5D+00 * sin ( x(1) * x(2) ) - x(2) / pi - x(1) g(2) = ( 4.0D+00 * pi - 1.0D+00 ) * ( exp ( 2.0D+00 * x(1) ) - E ) & / ( 4.0D+00 * pi ) + E * x(2) / pi - 2.0D+00 * E * x(1) return end subroutine p04_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P04_JAC evaluates the jacobian for problem 4. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ), parameter :: E = 2.71828182845904523536D+00 real ( kind = 8 ) gy(2) integer ( kind = 4 ) option real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 real ( kind = 8 ) x(nvar) real ( kind = 8 ) y(3) jac(1:nvar,1:nvar) = 0.0D+00 jac(1,1) = 0.5D+00 * x(2) * cos ( x(1) * x(2) ) - 1.0D+00 jac(2,1) = ( 4.0D+00 * pi - 1.0D+00 ) & * 2.0D+00 * exp ( 2.0D+00 * x(1) ) & / ( 4.0D+00 * pi ) - 2.0D+00 * E jac(1,2) = 0.5D+00 * x(1) * cos ( x(1) * x(2) ) - 1.0D+00 / pi jac(2,2) = E / pi ! ! Get the starting point ! call p04_start ( option, nvar, y ) ! ! Get the function value at the starting point ! call p04_gx ( y, gy ) jac(1,3) = gy(1) jac(2,3) = gy(2) return end subroutine p04_nvar ( option, nvar ) !*****************************************************************************80 ! !! P04_NVAR sets the number of variables for problem 4. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 3 return end subroutine p04_option_num ( option_num ) !*****************************************************************************80 ! !! P04_OPTION_NUM returns the number of options for problem 4. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p04_start ( option, nvar, x ) !*****************************************************************************80 ! !! P04_START returns a starting point for problem 4. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:3) = (/ 0.4D+00, 3.0D+00, 0.0D+00 /) return end subroutine p04_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P04_STEPSIZE returns step sizes for problem 4. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.300D+00 hmin = 0.001D+00 hmax = 25.000D+00 return end subroutine p04_title ( option, title ) !*****************************************************************************80 ! !! P04_TITLE sets the title for problem 4. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'Broyden function' return end subroutine p05_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P05_FUN evaluates the function for problem 5. ! ! Title: ! ! The Wacker function ! ! Description: ! ! The function is of the form ! ! F(1) = ( 1 - A * X(4) ) * X(1) + X(4) * exp ( - X(2) ) / 3.0D+00 ! + X(4) * ( A - 1 - 1/(3*E) ) ! ! F(2) = ( 1 - A * X(4) ) * X(2) - X(4) * log ( 1 + X(3) * X(3) ) / 5 ! + X(4) * ( A - 1 - log(2)/5 ) ! ! F(3) = ( 1 - A * X(3) ) * X(3) + X(4) * sin ( X(1) ) ! + X(4) * ( A - 1 - sin(1) ) ! ! with ! ! A is a parameter, and ! E is the base of the natural logarithm system, EXP(1.0). ! ! Starting Point: ! ! ( 0, 0, 0, 0 ) ! ! Options: ! ! OPTION = 1, ! A = 0.1; ! OPTION = 2, ! A = 0.5; ! OPTION = 3, ! A = 1.0. ! ! Special points: ! ! ! The value of the solution for which X(3) is 1 depends on the option ! chosen: ! ! Option X(1) X(2) X(3) X(4) ! ! 1 ( 1.147009, 1.431931, 1.000000, 1.084425 ). ! 2 ( 0.2412182, 0.4558247, 1.000000, 0.4534797 ). ! 3 ( 0.0000000, 0.0000000, 1.000000, 0.000000 ). ! ! For option 3, there is a limit point in variable X(4): ! ! ( -0.07109918, 0.06921115, 0.5009694, 0.2739685 ). ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 28 January 2004 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Hans-Joerg Wacker, Erich Zarzer, Werner Zulehner, ! Optimal Stepsize Control for the Globalized Newton Method, ! in Continuation Methods, ! edited by Hans-Joerg Wacker, ! Academic Press, 1978, ! ISBN: 0127292500, ! LC: QA1.S899. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) aval real ( kind = 8 ), parameter :: E = 2.71828182845904523536D+00 real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) if ( option == 1 ) then aval = 0.1D+00 else if ( option == 2 ) then aval = 0.5D+00 else aval = 1.0D+00 end if fx(1) = ( 1.0D+00 - aval * x(4) ) * x(1) & + x(4) * exp ( - x(2) ) / 3.0D+00 & + x(4) * ( aval - 1.0D+00 - 1.0D+00 / ( 3.0D+00 * E ) ) fx(2) = ( 1.0D+00 - aval * x(4) ) * x(2) & - x(4) * log ( 1.0D+00 + x(3) * x(3) ) / 5.0D+00 & + x(4) * ( aval - 1.0D+00 - log ( 2.0D+00 ) / 5.0D+00 ) fx(3) = ( 1.0D+00 - aval * x(3) ) * x(3) & + x(4) * sin ( x(1) ) & + x(4) * ( aval - 1.0D+00 - sin ( 1.0D+00 ) ) return end subroutine p05_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P05_JAC evaluates the jacobian for problem 5. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) aval real ( kind = 8 ), parameter :: E = 2.71828182845904523536D+00 integer ( kind = 4 ) option real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 if ( option == 1 ) then aval = 0.1D+00 else if ( option == 2 ) then aval = 0.5D+00 else aval = 1.0D+00 end if jac(1,1) = 1.0D+00 - aval * x(4) jac(1,2) = - x(4) * exp ( - x(2) ) / 3.0D+00 jac(1,3) = 0.0D+00 jac(1,4) = - aval * x(1) + exp ( - x(2) ) / 3.0D+00 & + ( aval - 1.0D+00 - 1.0D+00 / ( 3.0D+00 * E ) ) jac(2,1) = 0.0D+00 jac(2,2) = 1.0D+00 - aval * x(4) jac(2,3) = - 2.0D+00 * x(3) * x(4) / ( 5.0D+00 * ( 1.0D+00 + x(3) * x(3) ) ) jac(2,4) = - aval * x(2) - log ( 1.0D+00 + x(3) * x(3) ) / 5.0D+00 & + ( aval - 1.0D+00 - log ( 2.0D+00 ) / 5.0D+00 ) jac(3,1) = x(4) * cos ( x(1) ) jac(3,2) = 0.0D+00 jac(3,3) = 1.0D+00 - 2.0D+00 * aval * x(3) jac(3,4) = sin ( x(1) ) + ( aval - 1.0D+00 - sin ( 1.0D+00 ) ) return end subroutine p05_nvar ( option, nvar ) !*****************************************************************************80 ! !! P05_NVAR sets the number of variables for problem 5. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 4 return end subroutine p05_option_num ( option_num ) !*****************************************************************************80 ! !! P05_OPTION_NUM returns the number of options for problem 5. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 3 return end subroutine p05_start ( option, nvar, x ) !*****************************************************************************80 ! !! P05_START returns a starting point for problem 5. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:4) = 0.0D+00 return end subroutine p05_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P05_STEPSIZE returns step sizes for problem 5. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.300D+00 hmin = 0.001D+00 hmax = 25.000D+00 return end subroutine p05_title ( option, title ) !*****************************************************************************80 ! !! P05_TITLE sets the title for problem 5. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Wacker function, A = 0.1.' else if ( option == 2 ) then title = 'Wacker function, A = 0.5.' else if ( option == 3 ) then title = 'Wacker function, A = 1.0.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P05_TITLE - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p06_barray ( b ) !*****************************************************************************80 ! !! P06_BARRAY sets the B array. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 30 August 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, real ( kind = 8 ) B(5,8), the array of coefficients for the linear ! part of the aircraft stability function. ! implicit none real ( kind = 8 ) b(5,8) real ( kind = 8 ), parameter, dimension ( 5, 8 ) :: b_save = reshape ( (/ & -3.933D+00, 0.0D+00, 0.002D+00, 0.0D+00, 0.0D+00, & 0.107D+00, -0.987D+00, 0.0D+00, 1.0D+00, 0.0D+00, & 0.126D+00, 0.0D+00, -0.235D+00, 0.0D+00, -1.0D+00, & 0.0D+00, -22.95D+00, 0.0D+00, -1.0D+00, 0.0D+00, & -9.99D+00, 0.0D+00, 5.67D+00, 0.0D+00, -0.196D+00, & 0.0D+00, -28.37D+00, 0.0D+00, -0.168D+00, 0.0D+00, & -45.83D+00, 0.0D+00, -0.921D+00, 0.0D+00, -0.0071D+00, & -7.64D+00, 0.0D+00, -6.51D+00, 0.0D+00, 0.0D+00 /), (/ 5, 8 /) ) b(1:5,1:8) = b_save(1:5,1:8) return end subroutine p06_carray ( c ) !*****************************************************************************80 ! !! P06_CARRAY sets the C array. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, real ( kind = 8 ) C(5,8,8), the array of coefficients for the ! nonlinear part of the aircraft stability function. ! implicit none real ( kind = 8 ) c(5,8,8) integer ( kind = 4 ) i integer ( kind = 4 ) j integer ( kind = 4 ) k c(1:5,1:8,1:8) = 0.0D+00 c(1,2,3) = - 0.727D+00 c(1,3,4) = 8.39D+00 c(1,4,5) = - 684.4D+00 c(1,4,7) = + 63.5D+00 c(2,1,3) = + 0.949D+00 c(2,1,5) = + 0.173D+00 c(3,1,2) = - 0.716D+00 c(3,1,4) = - 1.578D+00 c(3,4,7) = + 1.132D+00 c(4,1,5) = - 1.0D+00 c(5,1,4) = + 1.0D+00 return end subroutine p06_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P06_FUN evaluates the function for problem 6. ! ! Title: ! ! The aircraft stability problem. ! ! Description: ! ! The equations describe the behavior of an aircraft under the ! control of a pilot. The variables are ! ! X(1) = roll ! X(2) = pitch ! X(3) = yaw ! X(4) = angle of attack ! X(5) = sideslip ! X(6) = elevator ! X(7) = aileron ! X(8) = rudder ! ! The function is of the following form ! ! For indices I=1 through 5, ! ! F(I) = SUM ( 1 <= J <= 8 ) B(I,J) * X(J) ! + SUM ( 1 <= J <= 8, 1 <= K <= 8 ) C(I,J,K) * X(J) * X(K) ! ! with the last two equations fixing the values of the elevator ! and rudder: ! ! F(6) = X(6) - value ! F(7) = X(8) ! ! Note that in the paper by Melhem and Rheinboldt, there are two ! mistakes in the description of the function PHI(Y,U). In both ! cases, the factor "Y4*Y2" should be replaced by "Y4*U2". ! ! Options: ! ! There are five options, which vary in the value they fix the ! elevator value in function 6: ! ! Option Elevator Value Limit Points in X(7) ! ! 1 -0.050 1 ! 2 -0.008 3 ! 3 0.0D+00 2 ! 4 0.05 1 ! 5 0.1 1 ! ! Special points: ! ! Melhem and Rheinboldt list the following limit points in X(7) ! (note that Melhem has B(4,1)=1.0, B(4,2)=0.0) ! ! X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) ! ! -2.9691 0.8307 -0.0727 0.4102 -0.2688 -0.05 0.5091 0.0 ! ! -2.8158 -0.1748 -0.0894 0.0263 0.0709 -0.008 0.2044 0.0 ! -3.7571 -0.6491 -0.3935 0.0918 0.1968 -0.008 -0.0038 0.0 ! -4.1637 0.0922 -0.0926 0.0224 -0.0171 -0.008 0.3782 0.0 ! ! -2.5839 -0.2212 -0.0540 0.0135 0.0908 0.0 0.1860 0.0 ! -3.9007 -1.1421 -0.5786 0.1328 0.3268 0.0 -0.5070 0.0 ! ! -2.3610 -0.7236 0.0327 -0.0391 0.2934 0.05 0.2927 0.0 ! ! -2.2982 1.4033 0.0632 -0.0793 0.5833 0.10 0.5833 0.0 ! ! Rheinboldt lists the following limit points in X(7), with ! B(4,1)=0.0, B(4,2)=1.0: ! ! X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) ! ! 2.9648 0.8255 0.0736 0.0413 0.2673 -0.050 -0.0504 0.0 ! ! 2.8173 -0.1762 0.0899 0.0264 -0.0714 -0.008 -0.2049 0.0 ! 3.7579 -0.6554 0.3865 0.0925 -0.1986 -0.008 0.0062 0.0 ! 4.1638 0.0891 0.0948 0.0228 0.1623 -0.008 -0.3776 0.0 ! ! 2.5873 -0.2235 0.0546 0.0136 -0.0916 0.000 -0.1869 0.0 ! 3.9005 -1.1481 0.5815 0.1335 -0.3285 0.000 0.5101 0.0 ! ! 2.3639 -0.7297 -0.3160 -0.0387 -0.2958 0.050 -0.2957 0.0 ! ! 2.2992 -1.4102 -0.0618 -0.0790 -0.5862 0.100 -0.6897 0.0 ! ! Rheinboldt lists the following bifurcation points: ! ! X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) ! ! 4.482 0.1632 0.0237 0.0062 0.0352 -0.0006 -0.3986 0.0 ! 3.319 -0.1869 0.1605 0.0437 -0.0688 -0.0125 -0.2374 0.0 ! 4.466 0.1467 0.0404 0.0097 0.0308 -0.0061 -0.3995 0.0 ! -3.325 0.1880 -0.1614 0.0439 0.0691 -0.0124 0.2367 0.0 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Raman Mehra, William Kessel, James Carroll, ! Global stability and contral analysis of aircraft at high angles of attack, ! Technical Report CR-215-248-1, -2, -3, ! Office of Naval Research, June 1977. ! ! Rami Melhem, Werner Rheinboldt, ! A Comparison of Methods for Determining Turning Points of ! Nonlinear Equations, ! Computing, ! Volume 29, Number 3, September 1982, pages 201-226. ! ! Albert Schy, Margery Hannah, ! Prediction of Jump Phenomena in Roll-coupled Maneuvers of Airplanes, ! Journal of Aircraft, ! Volume 14, Number 4, 1977, pages 375-382. ! ! John Young, Albert Schy, Katherine Johnson,, ! Prediction of Jump Phenomena in Aircraft Maneuvers, Including ! Nonlinear Aerodynamic Effects, ! Journal of Guidance and Control, ! Volume 1, Number 1, 1978, pages 26-31. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) b(5,8) real ( kind = 8 ) c(5,8,8) real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j integer ( kind = 4 ) k real ( kind = 8 ) val real ( kind = 8 ) x(nvar) ! ! Compute the linear term. ! call p06_barray ( b ) fx(1:5) = matmul ( b(1:5,1:8), x(1:8) ) ! ! Compute the nonlinear terms. ! call p06_carray ( c ) do i = 1, 5 do j = 1, 8 do k = 1, 8 fx(i) = fx(i) + c(i,j,k) * x(j) * x(k) end do end do end do ! ! Set function values for two fixed variables. ! if ( option == 1 ) then val = - 0.050D+00 else if ( option == 2 ) then val = - 0.008D+00 else if ( option == 3 ) then val = 0.000D+00 else if ( option == 4 ) then val = 0.050D+00 else if ( option == 5 ) then val = 0.100D+00 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P06_FUN - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if fx(6) = x(6) - val fx(7) = x(8) return end subroutine p06_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P06_JAC evaluates the jacobian for problem 6. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) b(5,8) real ( kind = 8 ) c(5,8,8) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) k real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 ! ! Set the jacobian to the linear coefficients. ! call p06_barray ( b ) jac(1:5,1:8) = b(1:5,1:8) ! ! Add the nonlinear terms. ! call p06_carray ( c ) do i = 1, 5 do j = 1, 8 do k = 1, 8 jac(i,j) = jac(i,j) + ( c(i,j,k) + c(i,k,j) ) * x(k) end do end do end do ! ! Constraint equations. ! jac(6,6) = 1.0D+00 jac(7,8) = 1.0D+00 return end subroutine p06_nvar ( option, nvar ) !*****************************************************************************80 ! !! P06_NVAR sets the number of variables for problem 6. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 8 return end subroutine p06_option_num ( option_num ) !*****************************************************************************80 ! !! P06_OPTION_NUM returns the number of options for problem 6. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 5 return end subroutine p06_start ( option, nvar, x ) !*****************************************************************************80 ! !! P06_START returns a starting point for problem 6. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) if ( option == 1 ) then x(1:nvar) = (/ & 1.06001162985175758D-03, & 5.12061216467178115D-02, & 5.79953409787390485D-05, & 5.96060845777059631D-02, & 2.64683802731226678D-05, & -5.00000000000000000D-02, & 0.00000000000000000D+00, & 0.00000000000000000D+00 /) else if ( option == 2 ) then x(1:nvar) = (/ & 0.000001548268247D+00, & 0.008192973225663D+00, & -0.000000682134573D+00, & 0.009536973221178D+00, & 0.000002896734870D+00, & -0.008000000000000D+00, & 0.000018188778989D+00, & 0.000000000000000D+00 /) else if ( option == 3 ) then x(1:nvar) = (/ & 0.0D+00, & 0.0D+00, & 0.0D+00, & 0.0D+00, & 0.0D+00, & 0.0D+00, & 0.0D+00, & 0.0D+00 /) else if ( option == 4 ) then x(1:nvar) = (/ & -0.000010655314069D+00, & -0.051206082422980D+00, & 0.000005600187501D+00, & -0.059606082643400D+00, & -0.000020891016199D+00, & 0.050000000000000D+00, & -0.000122595323216D+00, & 0.000000000000000D+00 /) else if ( option == 5 ) then x(1:nvar) = (/ & -0.000027083319493D+00, & -0.102412164106124D+00, & 0.000014540858026D+00, & -0.119212165322433D+00, & -0.000048014067202D+00, & 0.100000000000000D+00, & -0.000267808407544D+00, & 0.000000000000000D+00 /) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P06_START - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p06_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P06_STEPSIZE returns step sizes for problem 6. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = - 0.250D+00 hmin = 0.001D+00 hmax = 0.500D+00 return end subroutine p06_title ( option, title ) !*****************************************************************************80 ! !! P06_TITLE sets the title for problem 6. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Aircraft function, x(6) = - 0.050.' else if ( option == 2 ) then title = 'Aircraft function, x(6) = - 0.008.' else if ( option == 3 ) then title = 'Aircraft function, x(6) = 0.000.' else if ( option == 4 ) then title = 'Aircraft function, x(6) = + 0.050.' else if ( option == 5 ) then title = 'Aircraft function, x(6) = + 0.100.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P06_TITLE - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p07_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P07_FUN evaluates the function for problem 7. ! ! Title: ! ! Cell kinetics problem. ! ! Description: ! ! The function is of the form ! ! F(I) = Sum ( 1 <= J <= NVAR-1) ! A(I,J) * X(J) + RHO ( X(I) ) - X(NVAR) ! ! with tridiagonal matrix A. ! ! Special points: ! ! Limit points in the variable NVAR are sought. There are two: ! ! X(1) X(2) X(3) X(4) X(5) X(6) ! ! ( 1.048362, 1.048362, 1.048362, 1.048362, 1.048362, 34.35693 ). ! ( 8.822219, 8.822219, 8.822219, 8.822219, 8.822218, 18.88707 ). ! ! There are also four bifurcation points. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Werner Rheinboldt, ! Solution Fields of Nonlinear Equations and Continuation Methods, ! SIAM Journal on Numerical Analysis, ! Volume 17, Number 2, April 1980, pages 221-237. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) ! ! RHO(X) = 100.0D+00 * X / ( 1 + X + X * X ) ! do i = 1, nvar - 1 fx(i) = 100.0D+00 * x(i) / ( 1.0D+00 + x(i) + x(i) * x(i) ) - x(nvar) end do ! ! The tridiagonal matrix A = ( 2 -1 0 0 0 0 ... ) ! ( -1 2 -1 0 0 0 ... ) ! ( 0 -1 2 -1 0 0 ... ) ! fx(1) = fx(1) + 2.0D+00 * x(1) - x(2) do i = 2, nvar - 2 fx(i) = fx(i) - x(i-1) + 3.0D+00 * x(i) - x(i+1) end do fx(nvar-1) = fx(nvar-1) - x(nvar-2) + 2.0D+00 * x(nvar-1) return end subroutine p07_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P07_JAC evaluates the jacobian for problem 7. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 do i = 1, nvar - 1 jac(i,i) = 100.0D+00 * ( 1.0D+00 - x(i) * x(i) ) & / ( 1.0D+00 + x(i) + x(i) * x(i) )**2 end do jac(1,1) = jac(1,1) + 2.0D+00 jac(1,2) = jac(1,2) - 1.0D+00 jac(1,nvar) = jac(1,nvar) - 1.0D+00 do i = 2, nvar - 2 jac(i,i-1) = jac(i,i-1) - 1.0D+00 jac(i,i) = jac(i,i) + 3.0D+00 jac(i,i+1) = jac(i,i+1) - 1.0D+00 jac(i,nvar) = jac(i,nvar) - 1.0D+00 end do jac(nvar-1,nvar-2) = jac(nvar-1,nvar-2) - 1.0D+00 jac(nvar-1,nvar-1) = jac(nvar-1,nvar-1) + 2.0D+00 jac(nvar-1,nvar) = jac(nvar-1,nvar) - 1.0D+00 return end subroutine p07_nvar ( option, nvar ) !*****************************************************************************80 ! !! P07_NVAR sets the number of variables for problem 7. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 6 return end subroutine p07_option_num ( option_num ) !*****************************************************************************80 ! !! P07_OPTION_NUM returns the number of options for problem 7. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p07_start ( option, nvar, x ) !*****************************************************************************80 ! !! P07_START returns a starting point for problem 7. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 return end subroutine p07_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P07_STEPSIZE returns step sizes for problem 7. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 1.000D+00 hmin = 0.001D+00 hmax = 1.000D+00 return end subroutine p07_title ( option, title ) !*****************************************************************************80 ! !! P07_TITLE sets the title for problem 7. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'Cell kinetics problem, seeking limit points.' return end subroutine p08_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P08_FUN evaluates the function for problem 8. ! ! Title: ! ! Riks's mechanical problem. ! ! Description: ! ! The equations describe the equilibrium state of a structure made of ! three springs with a common movable endpoint and the other ! endpoints fixed. A load is applied to the common endpoint. ! ! X(1), X(2), and X(3) are the x, y, and z coordinates of the ! common point. ! X(4) is the magnitude of the load which is applied in the ! X direction. ! ! If C(I) is the spring constant for the I-th spring, and A(I,J) ! is the J-th coordinate of the I-th fixed endpoint, then the ! equation is: ! ! F(J) = SUM(I=1,3) COEF(I)*(A(I,J)-X(J)) + P(J) ! ! where ! ! COEF(I) = C(I) * (NORM(A(I,*)-NORM(X-A(I,*))) / NORM(X-A(I,*) ) ! ! and ! ! P=(X(4),X(5),X(6)) is an applied load, and ! ! NORM(X) is the euclidean norm, and ! ! c(1) + c(2) + c(3) = 1.0D+00 ! ! Two augmenting equations control the load vector P: ! ! F(4) = X(ival1) - val1. ! F(5) = X(ival2) - val2. ! ! For this example, ! ! ival1=4, val1=0 ! ival2=5, val2=0 ! ! and hence the load is all in the Z direction. ! ! We seek limit points in X(6). ! ! In Riks's paper, there seem to be limit points in X(6) at 4.10 and ! -3.84. The current code does not confirm this. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! E Riks, ! The Application of Newton's Method to the Problem of Elastic Stability, ! Transactions of the ASME, Journal of Applied Mechanics, ! December 1972, pages 1060-1065. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) anrm real ( kind = 8 ) aval(3,3) real ( kind = 8 ) cval(3) real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) ival1 integer ( kind = 4 ) ival2 integer ( kind = 4 ) j integer ( kind = 4 ) k real ( kind = 8 ) val1 real ( kind = 8 ) val2 real ( kind = 8 ) x(nvar) real ( kind = 8 ) xmanrm call p08_gx ( aval, cval ) do i = 1, 3 fx(i) = 0.0D+00 do j = 1, 3 ! ! Compute norms. ! anrm = 0.0D+00 xmanrm = 0.0D+00 do k = 1, 3 anrm = anrm + aval(j,k)**2 xmanrm = xmanrm + ( x(k) - aval(j,k) )**2 end do anrm = sqrt ( anrm ) xmanrm = sqrt ( xmanrm ) fx(i) = fx(i) + cval(j) * ( 1.0D+00 - anrm / xmanrm ) & * ( x(i) - aval(j,i) ) end do end do ! ! Add the load vector: ( X(4), X(5), X(6) ). ! do i = 1, 3 fx(i) = fx(i) + x(i+3) end do ! ! Get constraints. ! call p08_hx ( option, ival1, ival2, val1, val2 ) fx(4) = x(ival1) - val1 fx(5) = x(ival2) - val2 return end subroutine p08_gx ( aval, cval ) !*****************************************************************************80 ! !! P08_GX sets data used for Rik's mechanical problem. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, real ( kind = 8 ) AVAL(3,3); for each I, the values of AVAL(I,*) ! record the (X,Y,Z) coordinates of the I-th support point. ! ! Output, real ( kind = 8 ) CVAL(3), the values of the normalized spring ! constants. ! implicit none real ( kind = 8 ) aval(3,3) real ( kind = 8 ) cval(3) aval(1,1) = 2.0D+00 aval(1,2) = 0.0D+00 aval(1,3) = 0.0D+00 aval(2,1) = - 1.0D+00 aval(2,2) = 1.0D+00 aval(2,3) = 0.0D+00 aval(3,1) = - 1.0D+00 aval(3,2) = - 2.0D+00 aval(3,3) = 1.0D+00 cval(1) = 10.0D+00 / 21.0D+00 cval(2) = 6.0D+00 / 21.0D+00 cval(3) = 5.0D+00 / 21.0D+00 return end subroutine p08_hx ( option, ival1, ival2, val1, val2 ) !*****************************************************************************80 ! !! P08_HX reports the constraint equation data. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) IVAL1, IVAL2, the indices of the two ! constrained variables. ! ! Output, real ( kind = 8 ) VAL1, VAL2, the values to which the two ! constrained variables are to be set. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) ival1 integer ( kind = 4 ) ival2 real ( kind = 8 ) val1 real ( kind = 8 ) val2 ival1 = 4 val1 = 0.0D+00 ival2 = 5 val2 = 0.0D+00 return end subroutine p08_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P08_JAC evaluates the jacobian for problem 8. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) anrm real ( kind = 8 ) aval(3,3) real ( kind = 8 ) cval(3) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) ival1 integer ( kind = 4 ) ival2 integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) k integer ( kind = 4 ) l real ( kind = 8 ) val1 real ( kind = 8 ) val2 real ( kind = 8 ) x(nvar) real ( kind = 8 ) xmanrm jac(1:nvar,1:nvar) = 0.0D+00 call p08_gx ( aval, cval ) do i = 1, 3 do j = 1, 3 do k = 1, 3 ! ! Compute norms. ! anrm = 0.0D+00 xmanrm = 0.0D+00 do l = 1, 3 anrm = anrm + aval(k,l)**2 xmanrm = xmanrm + ( x(l) - aval(k,l) )**2 end do anrm = sqrt ( anrm ) xmanrm = sqrt ( xmanrm ) jac(i,j) = jac(i,j) + cval(k) * anrm * ( x(i) - aval(k,i) ) & * ( x(j) - aval(k,j) ) / xmanrm**3 if ( i == j ) then jac(i,j) = jac(i,j) - cval(k) * anrm / xmanrm end if end do end do end do do i = 1, 3 jac(i,i) = jac(i,i) + 1.0D+00 end do ! ! Add the loads. ! jac(1,4) = 1.0D+00 jac(2,5) = 1.0D+00 jac(3,6) = 1.0D+00 ! ! Apply the constraints. ! call p08_hx ( option, ival1, ival2, val1, val2 ) jac(4,ival1) = 1.0D+00 jac(5,ival2) = 1.0D+00 return end subroutine p08_nvar ( option, nvar ) !*****************************************************************************80 ! !! P08_NVAR sets the number of variables for problem 8. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 6 return end subroutine p08_option_num ( option_num ) !*****************************************************************************80 ! !! P08_OPTION_NUM returns the number of options for problem 8. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p08_start ( option, nvar, x ) !*****************************************************************************80 ! !! P08_START returns a starting point for problem 8. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) ival1 integer ( kind = 4 ) ival2 real ( kind = 8 ) val1 real ( kind = 8 ) val2 real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 call p08_hx ( option, ival1, ival2, val1, val2 ) x(ival1) = val1 x(ival2) = val2 return end subroutine p08_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P08_STEPSIZE returns step sizes for problem 8. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 1.000D+00 hmin = 0.001D+00 hmax = 1.000D+00 return end subroutine p08_title ( option, title ) !*****************************************************************************80 ! !! P08_TITLE sets the title for problem 8. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'Riks mechanical problem, seeking limit points.' return end subroutine p09_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P09_FUN evaluates the function for problem 9. ! ! Title: ! ! Oden mechanical problem. ! ! Description: ! ! The equations describe the equilibrium of a simple two bar ! framework, with one common endpoint, and the other endpoints ! fixed. A load is applied to the common endpoint. The bars are ! constructed of an isotropic hookean material. ! ! The function is of the form ! ! F(1) = X(1)**3 - 3*height*X(1)**2 + 2*height**2*X(1) ! +X(1)*X(2)**2 - height*X(2)**2 - X(3)*cos(X(4)) ! ! F(2) = X(1)**2*X(2) - 2*height*X(1)*X(2) + X(2)**3 + 2*X(2) ! -X(3)*sin(X(4)) ! ! F(3) = X(IVAL) - VAL ! ! with ! ! HEIGHT=2.0D+00 ! IVAL=4 ! VAL varying, depending on the option ! ! Options: ! ! VAL IT XIT LIM ! ! 1 0.00, 1, 4.0, 1 ! 2 0.25, 1, 4.0, 1 ! 3 0.50, 1, 4.0, 1 ! 4 1.00, 1, 4.0, 1 ! 5 0.00, 1, 4.0, 2 ! 6 0.25, 1, 4.0, 2 ! 7 0.50, 1, 4.0, 2 ! 8 1.00, 1, 4.0, 2 ! 9 0.00, 1, 4.0, 3 ! 10 0.25, 1, 4.0, 3 ! 11 0.50, 1, 4.0, 3 ! 12 1.00, 1, 4.0, 3 ! 13 0.00, 0, 0. ! ! For options 1, 5, and 9, the target point is (4,0,0,0). ! ! For option 9, there are the following limit points in X(3) ! ! (2+-2/sqrt(3), 0, +-16/sqrt(27), 0) ! ! For skew loads (X(4) nonzero) there are various limit points. ! ! Melhem lists, ! ! (0.5903206, 0.8391448, 0.9581753, 1.252346) ! (2.705446, 0.6177675, 0.9581753, 1.252346) ! ! with X(3),X(4) corresponding to a load vector of (.30,.91). ! ! Computational results with this program are: ! ! OPTION = 2 limit points in X(1) ! ! 2.816913 0.7396444 -2.348587 0.2500000 ! 1.183087 -0.7396445 2.348587 0.2500000 ! ! OPTION=3 limit points in X(1) ! ! 2.520900 0.8598542 -1.774344 0.5000000 ! 1.479100 -0.8598521 1.774346 0.5000000 ! ! OPTION=4 limit points in X(1) ! ! 2.210747 0.9241686 -1.209751 1.0000000 ! (limit point finder failed at second limit point) ! ! OPTION=6 limit points in X(2) ! ! 1.831179 1.424861 0.3392428 0.2500000 ! (apparently did not reach second limit point) ! ! OPTION=7 limit points in X(2) ! ! 1.697061 1.453503 0.6198216 0.2500000 ! 2.302939 -1.453503 -0.6198219 0.2500000 ! ! OPTION=8 limit points in X(2) ! ! 1.534293 1.555364 1.175649 1.0000000 ! 2.465706 -1.555364 -1.175648 1.0000000 ! ! OPTION=9 limit points in X(3) ! ! 0.8452995 0.0000000 3.079199 0.0000000 ! 3.154701 0.0000000 -3.079197 0.0000000 ! ! OPTION=10 limit points in X(3) ! ! 0.5800046 0.7846684 2.004746 0.2500000 ! 2.777765 0.5695726 -2.464886 0.2500000 ! ! OPTION=11 limit points in X(3) ! ! 0.6305253 0.9921379 1.779294 0.5000000 ! 2.501894 0.7202593 -1.846869 0.5000000 ! ! OPTION=12 limit points in X(3) ! ! 0.7650624 1.292679 1.837450 1.000000 ! 2.204188 0.8010838 -1.253382 1.000000 ! ! Bifurcation points occur at ! ! (2+-sqrt(2), 0, +-sqrt(2), 0) ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Rami Melhem, Werner Rheinboldt, ! A Comparison of Methods for Determining Turning Points of ! Nonlinear Equations, ! Computing, ! Volume 29, Number 3, September 1982, pages 201-226. ! ! John Oden, ! Finite Elements of Nonlinear Continua, ! Dover, 2006, ! ISBN: 0486449734, ! LC: QA808.2.O33. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) height integer ( kind = 4 ) option integer ( kind = 4 ) ival real ( kind = 8 ) val real ( kind = 8 ) x(nvar) real ( kind = 8 ) x1 real ( kind = 8 ) x2 real ( kind = 8 ) x3 real ( kind = 8 ) x4 call p09_gx ( option, height, ival, val ) x1 = x(1) x2 = x(2) x3 = x(3) x4 = x(4) fx(1) = x1**3 - 3.0D+00 * height * x1 * x1 & + 2.0D+00 * height * height * x1 & + x1 * x2 * x2 - height * x2 * x2 - x3 * cos ( x4 ) fx(2) = x1 * x1 * x2 - 2.0D+00 * height * x1 * x2 + x2**3 & + 2.0D+00 * x2 - x3 * sin ( x4 ) fx(3) = x(ival) - val return end subroutine p09_gx ( option, height, ival, val ) !*****************************************************************************80 ! !! P09_GX is used by problem 9. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 16 May 2001 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) HEIGHT, the height of the structure. ! ! Output, integer ( kind = 4 ) IVAL, the index of the variable being fixed. ! ! Output, real ( kind = 8 ) VAL, the value of the fixed variable. ! implicit none real ( kind = 8 ) height integer ( kind = 4 ) option integer ( kind = 4 ) ival real ( kind = 8 ) val height = 2.0D+00 ival = 4 if ( option == 1 .or. option == 5 .or. option == 9 ) then val = 0.00D+00 else if ( option == 2 .or. option == 6 .or. option == 10 ) then val = 0.25D+00 else if ( option == 3 .or. option == 7 .or. option == 11 ) then val = 0.50D+00 else if ( option == 4 .or. option == 8 .or. option == 12 ) then val = 1.00D+00 else if ( option == 13 ) then val = 0.00D+00 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P09_GX - Fatal error' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p09_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P09_JAC evaluates the jacobian for problem 9. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) height integer ( kind = 4 ) option integer ( kind = 4 ) ival real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) val real ( kind = 8 ) x(nvar) real ( kind = 8 ) x1 real ( kind = 8 ) x2 real ( kind = 8 ) x3 real ( kind = 8 ) x4 jac(1:nvar,1:nvar) = 0.0D+00 call p09_gx ( option, height, ival, val ) x1 = x(1) x2 = x(2) x3 = x(3) x4 = x(4) jac(1,1) = 3.0D+00 * x1 * x1 - 6.0D+00 * height * x1 & + 2.0D+00 * height * height + x2 * x2 jac(1,2) = 2.0D+00 * x1 * x2 - 2.0D+00 * height * x2 jac(1,3) = - cos ( x4 ) jac(1,4) = x3 * sin ( x4 ) jac(2,1) = 2.0D+00 * x1 * x2 - 2.0D+00 * height * x2 jac(2,2) = x1 * x1 - 2.0D+00 * height * x1 + 3.0D+00 * x2 * x2 + 2.0D+00 jac(2,3) = - sin ( x4 ) jac(2,4) = - x3 * cos ( x4 ) jac(3,1) = 0.0D+00 jac(3,2) = 0.0D+00 jac(3,3) = 0.0D+00 jac(3,4) = 0.0D+00 jac(3,ival) = 1.0D+00 return end subroutine p09_nvar ( option, nvar ) !*****************************************************************************80 ! !! P09_NVAR sets the number of variables for problem 9. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 4 return end subroutine p09_option_num ( option_num ) !*****************************************************************************80 ! !! P09_OPTION_NUM returns the number of options for problem 9. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 13 return end subroutine p09_start ( option, nvar, x ) !*****************************************************************************80 ! !! P09_START returns a starting point for problem 9. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) height integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) ival real ( kind = 8 ) val real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 call p09_gx ( option, height, ival, val ) x(ival) = val return end subroutine p09_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P09_STEPSIZE returns step sizes for problem 9. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.300D+00 hmin = 0.001D+00 hmax = 0.600D+00 return end subroutine p09_title ( option, title ) !*****************************************************************************80 ! !! P09_TITLE sets the title for problem 9. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 29 August 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Oden problem, VAL=0.00, Target X(1)=4.0, Limits in X(1).' else if ( option == 2 ) then title = 'Oden problem, VAL=0.25, Target X(1)=4.0, Limits in X(1).' else if ( option == 3 ) then title = 'Oden problem, VAL=0.50, Target X(1)=4.0, Limits in X(1).' else if ( option == 4 ) then title = 'Oden problem, VAL=1.00, Target X(1)=4.0, Limits in X(1).' else if ( option == 5 ) then title = 'Oden problem, VAL=0.00, Target X(1)=4.0, Limits in X(2).' else if ( option == 6 ) then title = 'Oden problem, VAL=0.25, Target X(1)=4.0, Limits in X(2).' else if ( option == 7 ) then title = 'Oden problem, VAL=0.50, Target X(1)=4.0, Limits in X(2).' else if ( option == 8 ) then title = 'Oden problem, VAL=1.00, Target X(1)=4.0, Limits in X(2).' else if ( option == 9 ) then title = 'Oden problem, VAL=0.00, Target X(1)=4.0, Limits in X(3).' else if ( option == 10 ) then title = 'Oden problem, VAL=0.25, Target X(1)=4.0, Limits in X(3).' else if ( option == 11 ) then title = 'Oden problem, VAL=0.50, Target X(1)=4.0, Limits in X(3).' else if ( option == 12 ) then title = 'Oden problem, VAL=1.00, Target X(1)=4.0, Limits in X(3).' else if ( option == 13 ) then title = 'Oden problem, VAL=0.00, no targets, no limits.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P09_TITLE - Fatal error!' write ( *, '(a)' ) ' Unrecognized option number.' stop end if return end subroutine p10_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P10_FUN evaluates the function for problem 10. ! ! Title: ! ! Torsion of a square rod, finite difference solution ! ! Description: ! ! The problem is a boundary value problem on (0,1) x (0,1) ! of the form: ! ! - d/dx ( PHI ( dU/dx, dU/dy ) * dU/dx ) ! - d/dy ( PHI ( dU/dx, dU/dy ) * dU/dy ) = G ( U, LAMBDA ) ! ! A standard finite difference approximation on a uniform mesh is ! applied to yield the equations, with X(1) through X(NVAR-1) storing ! the value of U at the mesh points, and X(NVAR) holding the value ! of LAMBDA. ! ! Options: ! ! Let S = dU/dX**2 + dU/dY**2. ! ! OPTION=1 ! ! PHI(S) = exp ( 5 * S ) ! ! OPTION=2 ! ! Let SBAR = ( 40 * S - 13 ) / 7 ! ! if ( S <= 0.15 ) then ! PHI = 1.0D+00 ! else if ( 0.15 <= S <= 0.50 ) then ! PHI = 5.5 + 4.5 * ( 3 * SBAR - SBAR**3 ) ! else if ( 0.50 <= S ) then ! PHI = 10.0D+00 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Werner Rheinboldt, ! On the Solution of Some Nonlinear Equations Arising in the ! Application of Finite Element Methods, ! in The Mathematics of Finite Elements and Applications II, ! edited by John Whiteman ! Academic Press, London, 1976, pages 465-482, ! LC: TA347.F5.M37. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) cx(2,4) real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) g real ( kind = 8 ) gp real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) ij integer ( kind = 4 ) option integer ( kind = 4 ) j integer ( kind = 4 ) jk integer ( kind = 4 ) k integer ( kind = 4 ) k1 integer ( kind = 4 ) k2 integer ( kind = 4 ) l integer ( kind = 4 ) ncol integer ( kind = 4 ) nrow real ( kind = 8 ) rlk real ( kind = 8 ) sc real ( kind = 8 ) uc(2) real ( kind = 8 ) ux(4) real ( kind = 8 ) x(nvar) nrow = 6 ncol = 6 h = 1.0D+00 / real ( nrow + 1, kind = 8 ) do i = 1, nrow do j = 1, ncol ij = ( j - 1 ) * nrow + i ! ! UC contains the two cornerpoints, ! if ( i == 1 .or. j == 1 ) then uc(1) = 0.0D+00 else jk = ij - nrow uc(1) = x(jk-1) end if if ( j == ncol .or. i == nrow ) then uc(2) = 0.0D+00 else jk = ij + nrow uc(2) = x(jk+1) end if ! ! UX contains the four side-points, ! if ( i == 1 ) then ux(1) = 0.0D+00 else ux(1) = x(ij-1) end if if ( i < nrow ) then ux(2) = x(ij+1) else ux(2) = 0.0D+00 end if if ( j == 1 ) then ux(3) = 0.0D+00 else jk = ij - nrow ux(3) = x(jk) end if if ( j < ncol ) then jk = ij + nrow ux(4) = x(jk) else ux(4) = 0.0D+00 end if ! ! CX contains the elements connected to the side points. ! ! k = 1, 2*qw calculated and stored in ( cx(1,k) + cx(2,k) ) ! k = 2, 2*qe calculated and stored in ( cx(1,k) + cx(2,k) ) ! k = 3, 2*qs calculated and stored in ( cx(1,k) + cx(2,k) ) ! k = 4, 2*qn calculated and stored in ( cx(1,k) + cx(2,k) ) ! sc = 0.0D+00 do k = 1, 4 if ( k == 1 .or. k == 3 ) then k1 = 1 k2 = 4 else k1 = 2 k2 = 3 end if do l = 1, 2 rlk = ( ux(k) - x(ij) )**2 if ( l == 1 ) then rlk = ( rlk + ( ux(k) - uc(k1) )**2 ) / h / h else rlk = ( rlk + ( x(ij) - ux(k2) )**2 ) / h / h end if call p10_gx ( option, rlk, g, gp ) cx(l,k) = g sc = sc + cx(l,k) end do end do ! ! sc = qn + qs + qe + qw ! fx(ij) = 0.5D+00 * sc * x(ij) - x(nvar) * h * h do k = 1, 4 fx(ij) = fx(ij) - 0.5D+00 * ux(k) * ( cx(1,k) + cx(2,k) ) end do end do end do return end subroutine p10_gx ( option, s, g, gp ) !*****************************************************************************80 ! !! P10_GX is used by problem 10. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, real ( kind = 8 ) S, the value of the argument of G. ! S = (d U/d X)**2 + (d U/d Y)**2. ! ! Output, real ( kind = 8 ) G, GP, the value of G(S) and d G(S)/d S. ! implicit none real ( kind = 8 ) g real ( kind = 8 ) gp integer ( kind = 4 ) option real ( kind = 8 ) s real ( kind = 8 ) sbar if ( option == 1 ) then g = exp ( 5.0D+00 * s ) gp = 5.0D+00 * exp ( 5.0D+00 * s ) else if ( option == 2 ) then if ( s <= 0.15D+00 ) then g = 1.0D+00 gp = 0.0D+00 else if ( 0.15D+00 < s .and. s < 0.5D+00 ) then sbar = ( 40.0D+00 * s - 13.0D+00 ) / 7.0D+00 g = 5.5D+00 + 2.25D+00 * sbar * ( 3.0D+00 - sbar * sbar ) gp = 270.0D+00 * ( 1.0D+00 - sbar * sbar ) / 7.0D+00 else g = 10.0D+00 gp = 0.0D+00 end if else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P10_GX - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p10_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P10_JAC evaluates the jacobian for problem 10. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) cx(2,4) real ( kind = 8 ) dx(2,4) real ( kind = 8 ) g real ( kind = 8 ) gp real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) ij integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) jk integer ( kind = 4 ) k integer ( kind = 4 ) k1 integer ( kind = 4 ) k2 integer ( kind = 4 ) l integer ( kind = 4 ) ncol integer ( kind = 4 ) nrow real ( kind = 8 ) rlk real ( kind = 8 ) sc real ( kind = 8 ) uc(2) real ( kind = 8 ) ux(4) real ( kind = 8 ) x(nvar) real ( kind = 8 ) xjac jac(1:nvar,1:nvar) = 0.0D+00 nrow = 6 ncol = 6 h = 1.0D+00 / real ( nrow + 1, kind = 8 ) do i = 1, nrow do j = 1, ncol uc(1) = 0.0D+00 uc(2) = 0.0D+00 ux(1:4) = 0.0D+00 ij = i + ( j - 1 ) * nrow if ( i /= 1 ) then ux(1) = x(ij-1) end if if ( i /= nrow ) then ux(2) = x(ij+1) end if if ( 1 < j ) then jk = ij - nrow ux(3) = x(jk) if ( i /= 1 ) then uc(1) = x(jk-1) end if end if if ( j < ncol ) then jk = ij + nrow ux(4) = x(jk) if ( i /= nrow ) then uc(2) = x(jk+1) end if end if sc = 0.0D+00 do k = 1, 4 if ( k == 1 .or. k == 3 ) then k1 = 1 else k1 = 2 end if k2 = 5 - k do l = 1, 2 rlk = ( ux(k) - x(ij) )**2 if ( l == 1 ) then rlk = ( rlk + ( ux(k) - uc(k1) )**2 ) / h / h else rlk = ( rlk + ( x(ij) - ux(k2) )**2 ) / h / h end if call p10_gx ( option, rlk, g, gp ) cx(l,k) = g dx(l,k) = gp sc = sc + cx(l,k) end do end do ! ! diagonal ! xjac = 0.5D+00 * sc do k = 1, 4 k2 = 5 - k xjac = xjac + dx(2,k) * ( x(ij) - ux(k) ) & * ( 2.0D+00 * x(ij) - ux(k) - ux(k2) ) / h / h xjac = xjac + dx(1,k) * ( x(ij) - ux(k) )**2 / h / h end do jac(ij,ij) = xjac ! ! off-diagonals ! do k = 1, 4 if ( k == 1 ) then if ( i == 1 ) then continue end if jk = ij - 1 else if ( k == 2 ) then if ( i == nrow ) then continue end if jk = ij + 1 else if ( k == 3 ) then if ( j == 1 ) then continue end if jk = ij - nrow else if ( k == 4 ) then if ( j == ncol ) then continue end if jk = ij + nrow end if if ( k == 1 .or. k == 3 ) then k1 = 1 else k1 = 2 end if k2 = 5 - k xjac = ( x(ij) - ux(k) ) & * ( dx(1,k) * ( 2.0D+00 * ux(k) - x(ij) - uc(k1) ) & + dx(2,k) * ( ux(k) - x(ij) ) + dx(2,k2) * ( ux(k2) - x(ij) ) ) xjac = xjac / h / h - 0.5D+00 * ( cx(1,k) + cx(2,k) ) jac(ij,jk) = xjac end do if ( i /= 1 .and. j /= 1 ) then jk = ij - nrow - 1 xjac = ( x(ij) - ux(1) ) * dx(1,1) * ( uc(1) - ux(1) ) & + ( x(ij) - ux(3) ) * dx(1,3) * ( uc(1) - ux(3) ) jac(ij,jk) = xjac / h / h end if if ( i /= nrow .and. j /= ncol ) then jk = ij + nrow + 1 xjac = ( x(ij) - ux(2) ) * dx(1,2) * ( uc(2) - ux(2) ) & + ( x(ij) - ux(4) ) * dx(1,4) * ( uc(2) - ux(4) ) jac(ij,jk) = xjac / h / h end if end do end do do i = 1, nvar - 1 jac(i,nvar) = - h * h end do return end subroutine p10_nvar ( option, nvar ) !*****************************************************************************80 ! !! P10_NVAR sets the number of variables for problem 10. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) ncol integer ( kind = 4 ) nrow integer ( kind = 4 ) nvar nrow = 6 ncol = 6 nvar = nrow * ncol + 1 return end subroutine p10_option_num ( option_num ) !*****************************************************************************80 ! !! P10_OPTION_NUM returns the number of options for problem 10. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 2 return end subroutine p10_start ( option, nvar, x ) !*****************************************************************************80 ! !! P10_START returns a starting point for problem 10. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 return end subroutine p10_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P10_STEPSIZE returns step sizes for problem 10. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 2.000D+00 hmin = 0.001D+00 hmax = 10.000D+00 return end subroutine p10_title ( option, title ) !*****************************************************************************80 ! !! P10_TITLE sets the title for problem 10. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Torsion of a square rod, finite difference, PHI(S)=EXP(5*S).' else if ( option == 2 ) then title = 'Torsion of a square rod, finite difference, PHI(S)=two levels.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P10_TITLE - Fatal error!' write ( *, '(a)' ) ' Unrecognized option number.' stop end if return end subroutine p11_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P11_FUN evaluates the function for problem 11. ! ! Title: ! ! Torsion of a square rod, finite element solution. ! ! Description: ! ! The problem is a boundary value problem on (0,1) x (0,1) ! of the form: ! ! - d/dx ( PHI ( dU/dx, dU/dy ) * dU/dx ) ! - d/dy ( PHI ( dU/dx, dU/dy ) * dU/dy ) = G ( U, LAMBDA ) ! ! On the 2-dimensional region [0,1] x [0,1], a regular square grid ! is used. If there are NSIDE nodes on a side, then the spacing ! is H=1/(NSIDE-1). The nodes are ordered from left to right, and ! from bottom to top, as are the resulting square elements: ! ! 21---22---23---24---25 ! ! ! ! ! ! ! ! 13 ! 14 ! 15 ! 16 ! ! ! ! ! ! ! ! 16---17---18---19---20 ! ! ! ! ! ! ! ! 09 ! 10 ! 11 ! 12 ! ! ! ! ! ! ! ! 11---12---13---14---15 ! ! ! ! ! ! ! ! 05 ! 06 ! 07 ! 08 ! ! ! ! ! ! ! ! 06---07---08---09---10 ! ! ! ! ! ! ! ! 01 ! 02 ! 03 ! 04 ! ! ! ! ! ! ! ! 01---02---03---04---05 ! ! On a single element, the local ordering of nodes and shape ! functions is ! ! 3----4 ! ! ! ! ! ! ! ! ! ! 1----2 ! ! Linear elements are used. If H is the length of a side, the shape ! function in a particular element associated with node 1 is: ! ! PSI(X,Y) = ( X - XRIGHT ) * ( Y - YTOP ) / H**2 ! ! where ! ! XRIGHT is the X coordinate of the right hand side of the element, ! YTOP is the Y coordinate of the top side of the element. ! ! Options: ! ! OPTION = 1: ! ! PHI = exp ( 5 * ( dUdX**2 + dUdY**2 ) ) ! ! G ( U, LAMBDA ) = - 5 * LAMBDA ! ! OPTION = 2: ! ! Let S = ( dUdX**2 + dUdY**2 ), ! SBAR = ( 40 * S - 13 ) / 7 ! ! if ( S <= 0.15 ) then ! PHI = 1.0D+00 ! else if ( 0.15 <= S <= 0.50 ) then ! PHI = 5.5 + 4.5 * ( 3 * SBAR - SBAR**3 ) ! else if ( 0.50 <= S ) then ! PHI = 10.0D+00 ! ! G ( U, LAMBDA ) = - 10 * LAMBDA ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 23 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Werner Rheinboldt, ! On the Solution of Some Nonlinear Equations Arising in the ! Application of Finite Element Methods, ! in The Mathematics of Finite Elements and Applications II, ! edited by John Whiteman, ! Academic Press, London, 1976, pages 465-482, ! LC: TA347.F5.M37. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ), parameter :: ngauss = 4 integer ( kind = 4 ), parameter :: nshape = 4 integer ( kind = 4 ), parameter :: nside = 5 real ( kind = 8 ) dpsidx(nshape) real ( kind = 8 ) dpsidy(nshape) real ( kind = 8 ) dudx real ( kind = 8 ) dudy real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) flam real ( kind = 8 ) flampl real ( kind = 8 ) flampu real ( kind = 8 ) hside integer ( kind = 4 ) i integer ( kind = 4 ) icol integer ( kind = 4 ) ielem integer ( kind = 4 ) option integer ( kind = 4 ) irow integer ( kind = 4 ) irowm1 integer ( kind = 4 ) jcol integer ( kind = 4 ) jgauss integer ( kind = 4 ) jrow integer ( kind = 4 ) jrowm1 integer ( kind = 4 ) kshape integer ( kind = 4 ) nelem integer ( kind = 4 ) nod integer ( kind = 4 ) node(nshape) real ( kind = 8 ) phi real ( kind = 8 ) phip real ( kind = 8 ) psi(nshape) real ( kind = 8 ) uval real ( kind = 8 ) wgauss(ngauss) real ( kind = 8 ) x(nvar) real ( kind = 8 ) xgauss(ngauss) real ( kind = 8 ) xmid real ( kind = 8 ) xval real ( kind = 8 ) ygauss(ngauss) real ( kind = 8 ) ymid real ( kind = 8 ) yval fx(1:nvar-1) = 0.0D+00 nelem = ( nside - 1 ) * ( nside - 1 ) hside = 1.0D+00 / real ( nside - 1, kind = 8 ) do ielem = 1, nelem ! ! From the element number IELEM, compute the indices of the four ! corners, in the order SW, SE, NW, NE. ! irowm1 = ( ielem - 1 ) / ( nside - 1 ) icol = ielem - irowm1 * ( nside - 1 ) irow = irowm1 + 1 xmid = hside * real ( 2 * icol - 1 ) / 2.0D+00 ymid = hside * real ( 2 * irow - 1 ) / 2.0D+00 node(1) = irowm1 * nside + icol node(2) = node(1) + 1 node(3) = node(1) + nside node(4) = node(3) + 1 ! ! Get the Gauss points for this element. ! call p11_gauss ( hside, xmid, ymid, wgauss, xgauss, ygauss ) ! ! For each Gauss point in this element, evaluate the integrand. ! do jgauss = 1, ngauss xval = xgauss(jgauss) yval = ygauss(jgauss) ! ! Evaluate the shape functions PSI and their derivatives. ! call p11_shape ( hside, xmid, xval, ymid, yval, psi, dpsidx, dpsidy ) ! ! Evaluate U and its derivatives. ! uval = 0.0D+00 dudx = 0.0D+00 dudy = 0.0D+00 do i = 1, nshape uval = uval + x(node(i)) * psi(i) dudx = dudx + x(node(i)) * dpsidx(i) dudy = dudy + x(node(i)) * dpsidy(i) end do ! ! Evaluate PHI ( DUDX, DUDY ). ! call p11_phi ( dudx, dudy, option, phi, phip ) ! ! Evaluate G ( U, LAMBDA ). ! call p11_gul ( option, x(nvar), flam, flampl, flampu ) ! ! Compute the inner product of the equation with each shape function ! and add to the appropriate function. ! do kshape = 1, nshape nod = node(kshape) jrowm1 = ( nod - 1 ) / nside jcol = nod - jrowm1 * nside jrow = jrowm1 + 1 if ( jrow == 1 .or. jrow == nside .or. & jcol == 1 .or. jcol == nside ) then fx(nod) = x(nod) else fx(nod) = fx(nod) + wgauss(jgauss) * hside * hside * & ( phi * ( dudx * dpsidx(kshape) + dudy * dpsidy(kshape) ) & + flam * psi(kshape) ) end if end do end do end do return end subroutine p11_gauss ( hside, xmid, ymid, wgauss, xgauss, ygauss ) !*****************************************************************************80 ! !! P11_GAUSS returns the Gauss quadrature abscissas and weights. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 23 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) HSIDE, the length of a side of the square. ! ! Input, real ( kind = 8 ) XMID, YMID, the coordinates of the center ! of the square. ! ! Output, real ( kind = 8 ) WGAUSS(4), the weights of the Gauss points. ! The weights are normalized for a square of unit area. ! ! Output, real ( kind = 8 ) XGAUSS(4), YGAUSS(4), the coordinates of the ! Gauss points. ! implicit none real ( kind = 8 ) alfa real ( kind = 8 ) hside real ( kind = 8 ) wgauss(4) real ( kind = 8 ) xgauss(4) real ( kind = 8 ) xmid real ( kind = 8 ) ygauss(4) real ( kind = 8 ) ymid alfa = 1.0D+00 / ( 2.0D+00 * sqrt ( 3.0D+00 ) ) wgauss(1:4) = 0.25D+00 xgauss(1) = xmid - alfa * hside xgauss(2) = xmid + alfa * hside xgauss(3) = xmid - alfa * hside xgauss(4) = xmid + alfa * hside ygauss(1) = ymid - alfa * hside ygauss(2) = ymid - alfa * hside ygauss(3) = ymid + alfa * hside ygauss(4) = ymid + alfa * hside return end subroutine p11_gul ( option, lambda, flam, flampl, flampu ) !*****************************************************************************80 ! !! P11_GUL computes G(U,LAMBDA) and dG/dU and dG/dLAMBDA. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, real ( kind = 8 ) LAMBDA, the value of LAMBDA. ! ! Output, real ( kind = 8 ) FLAM, FLAMPL, FLAMPU, the values of F(U,LAMBDA), ! d F(U,LAMBDA)/d LAMBDA, and d F(U,LAMBDA)/d U. ! implicit none real ( kind = 8 ) flam real ( kind = 8 ) flampl real ( kind = 8 ) flampu integer ( kind = 4 ) option real ( kind = 8 ) lambda if ( option == 1 ) then flam = - 5.0D+00 * lambda flampl = - 5.0D+00 flampu = 0.0D+00 else if ( option == 2 ) then flam = - 10.0D+00 * lambda flampl = - 10.0D+00 flampu = 0.0D+00 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P11_GUL - Fatal error!' write ( *, '(a,i8)' ) ' Illegal option = ', option stop end if return end subroutine p11_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P11_JAC evaluates the jacobian for problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ), parameter :: ngauss = 4 integer ( kind = 4 ), parameter :: nshape = 4 integer ( kind = 4 ), parameter :: nside = 5 integer ( kind = 4 ) nvar real ( kind = 8 ) dpsidx(nshape) real ( kind = 8 ) dpsidy(nshape) real ( kind = 8 ) dudx real ( kind = 8 ) dudy real ( kind = 8 ) flam real ( kind = 8 ) flampl real ( kind = 8 ) flampu real ( kind = 8 ) hside integer ( kind = 4 ) i integer ( kind = 4 ) icol integer ( kind = 4 ) ielem integer ( kind = 4 ) option integer ( kind = 4 ) irow integer ( kind = 4 ) irowm1 integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) jcol integer ( kind = 4 ) jgauss integer ( kind = 4 ) jrow integer ( kind = 4 ) jrowm1 integer ( kind = 4 ) kshape integer ( kind = 4 ) lshape integer ( kind = 4 ) nelem integer ( kind = 4 ) nod integer ( kind = 4 ) nod2 integer ( kind = 4 ) node(nshape) real ( kind = 8 ) phi real ( kind = 8 ) phip real ( kind = 8 ) psi(nshape) real ( kind = 8 ) term1 real ( kind = 8 ) term2 real ( kind = 8 ) uval real ( kind = 8 ) wgauss(ngauss) real ( kind = 8 ) x(nvar) real ( kind = 8 ) xgauss(ngauss) real ( kind = 8 ) xmid real ( kind = 8 ) xval real ( kind = 8 ) ygauss(ngauss) real ( kind = 8 ) ymid real ( kind = 8 ) yval jac(1:nvar,1:nvar) = 0.0D+00 nelem = ( nside - 1 ) * ( nside - 1 ) hside = 1.0D+00 / real ( nside - 1, kind = 8 ) do ielem = 1, nelem ! ! From element number, compute 4 node numbers ! in the order sw, se, nw, ne. ! irowm1 = ( ielem - 1 ) / ( nside - 1 ) icol = ielem - irowm1 * ( nside - 1 ) irow = irowm1 + 1 xmid = hside * real ( 2 * icol - 1 ) / 2.0D+00 ymid = hside * real ( 2 * irow - 1 ) / 2.0D+00 node(1) = irowm1 * nside + icol node(2) = node(1) + 1 node(3) = node(1) + nside node(4) = node(3) + 1 ! ! Get the Gauss quadrature points for this element. ! call p11_gauss ( hside, xmid, ymid, wgauss, xgauss, ygauss ) ! ! At each Gauss point in this element, evaluate the integrand. ! do jgauss = 1, ngauss xval = xgauss(jgauss) yval = ygauss(jgauss) ! ! Evaluate the shape functions. ! call p11_shape ( hside, xmid, xval, ymid, yval, psi, dpsidx, dpsidy ) ! ! Evaluate U and its derivatives. ! uval = 0.0D+00 dudx = 0.0D+00 dudy = 0.0D+00 do i = 1, nshape uval = uval + x(node(i)) * psi(i) dudx = dudx + x(node(i)) * dpsidx(i) dudy = dudy + x(node(i)) * dpsidy(i) end do ! ! Evaluate PHI ( DUDX, DUDY ). ! call p11_phi ( dudx, dudy, option, phi, phip ) ! ! Evaluate G ( U, LAMBDA ). ! call p11_gul ( option, x(nvar), flam, flampl, flampu ) ! ! Compute inner product of equation with each shape function ! and add to appropriate function. ! do kshape = 1, nshape nod = node(kshape) jrowm1 = ( nod - 1 ) / nside jcol = nod - jrowm1 * nside jrow = jrowm1 + 1 if ( jrow == 1 .or. jrow == nside .or. & jcol == 1 .or. jcol == nside ) then jac(nod,nod) = 1.0D+00 else do lshape = 1, nshape nod2 = node(lshape) term1 = phi * dpsidx(lshape) + 2.0D+00 * phip * & ( dudx * dudx * dpsidx(lshape) + dudx * dudy * dpsidy(lshape) ) term2 = phi * dpsidy(lshape) + 2.0D+00 * phip * & ( dudy * dudx * dpsidx(lshape) + dudy * dudy * dpsidy(lshape) ) jac(nod,nod2) = jac(nod,nod2) + wgauss(jgauss) * hside * hside * & ( term1 * dpsidx(kshape) + term2 * dpsidy(kshape) & + flampu * psi(lshape) * psi(kshape) ) end do jac(nod,nvar) = jac(nod,nvar) + wgauss(jgauss) * hside * hside * & flampl * psi(kshape) end if end do end do end do return end subroutine p11_nvar ( option, nvar ) !*****************************************************************************80 ! !! P11_NVAR sets the number of variables for problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 26 return end subroutine p11_option_num ( option_num ) !*****************************************************************************80 ! !! P11_OPTION_NUM returns the number of options for problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 12 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 2 return end subroutine p11_phi ( dudx, dudy, option, phi, phip ) !*****************************************************************************80 ! !! P11_PHI is used by problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) DUDX, DUDY, the values of dU/dX and dU/dY. ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) PHI, PHIP, the values of PHI(S) and d PHI(S)/d S, ! where S = dU/dX**2 + dU/dY**2. ! implicit none real ( kind = 8 ) dudx real ( kind = 8 ) dudy integer ( kind = 4 ) option real ( kind = 8 ) phi real ( kind = 8 ) phip real ( kind = 8 ) s real ( kind = 8 ) sbar s = dudx * dudx + dudy * dudy if ( option == 1 ) then phi = exp ( 5.0D+00 * s ) phip = 5.0D+00 * exp ( 5.0D+00 * s ) else if ( option == 2 ) then sbar = ( 40.0D+00 * s - 13.0D+00 ) / 7.0D+00 if ( s <= 0.15D+00 ) then phi = 1.0D+00 phip = 0.0D+00 else if ( 0.15D+00 <= s .and. s <= 0.5D+00 ) then phi = 5.5D+00 + 2.25D+00 * sbar * ( 3.0D+00 - sbar * sbar ) phip = 2.25D+00 * ( 3.0D+00 - 3.0D+00 * sbar * sbar ) * 40.0D+00 / 7.0D+00 else phi = 10.0D+00 phip = 0.0D+00 end if else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P11_PHI - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p11_shape ( hside, xmid, xval, ymid, yval, psi, dpsidx, dpsidy ) !*****************************************************************************80 ! !! P11_SHAPE evaluates the shape functions for problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) HSIDE, the length of a side of the square. ! ! Input, real ( kind = 8 ) XMID, the X coordinate of the center of ! the square. ! ! Input, real ( kind = 8 ) XVAL, the X coordinate of the point where the ! shape functions are to be evaluated. ! ! Input, real ( kind = 8 ) YMID, the Y coordinate of the center of ! the square. ! ! Input, real ( kind = 8 ) YVAL, the Y coordinate of the point where ! the shape functions are to be evaluated. ! ! Output, real ( kind = 8 ) PSI(4), the value of PSI (the shape functions) at ! (XVAL,YVAL). The shape functions are stored in the order ! SW, SE, NW, NE. ! ! Output, real ( kind = 8 ) DPSIDX(4), DPSIDY(4), the values of dPSI/dX ! and dPSI/dY at (XVAL,YVAL). ! implicit none real ( kind = 8 ) dpsidx(4) real ( kind = 8 ) dpsidy(4) real ( kind = 8 ) hside real ( kind = 8 ) psi(4) real ( kind = 8 ) xleft real ( kind = 8 ) xmid real ( kind = 8 ) xrite real ( kind = 8 ) xval real ( kind = 8 ) ybot real ( kind = 8 ) ymid real ( kind = 8 ) ytop real ( kind = 8 ) yval ! ! Set coordinates. ! xleft = xmid - 0.5D+00 * hside xrite = xmid + 0.5D+00 * hside ybot = ymid - 0.5D+00 * hside ytop = ymid + 0.5D+00 * hside ! ! Evaluate the shape functions. ! psi(1) = ( xval - xrite ) * ( yval - ytop ) / hside / hside psi(2) = - ( xval - xleft ) * ( yval - ytop ) / hside / hside psi(3) = - ( xval - xrite ) * ( yval - ybot ) / hside / hside psi(4) = ( xval - xleft ) * ( yval - ybot ) / hside / hside ! ! Evaluate the partial derivatives. ! dpsidx(1) = ( yval - ytop ) / hside / hside dpsidx(2) = - ( yval - ytop ) / hside / hside dpsidx(3) = - ( yval - ybot ) / hside / hside dpsidx(4) = ( yval - ybot ) / hside / hside dpsidy(1) = ( xval - xrite ) / hside / hside dpsidy(2) = - ( xval - xleft ) / hside / hside dpsidy(3) = - ( xval - xrite ) / hside / hside dpsidy(4) = ( xval - xleft ) / hside / hside return end subroutine p11_start ( option, nvar, x ) !*****************************************************************************80 ! !! P11_START returns a starting point for problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 10 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 return end subroutine p11_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P11_STEPSIZE returns step sizes for problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.12500D+00 hmin = 0.03125D+00 hmax = 4.00000D+00 return end subroutine p11_title ( option, title ) !*****************************************************************************80 ! !! P11_TITLE sets the title for problem 11. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'Torsion of a square rod, finite element solution.' return end subroutine p12_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P12_FUN evaluates the function for problem 12. ! ! Title: ! ! Materially nonlinear problem. ! ! Description: ! ! The problem is the two point boundary value problem ! ! U'' + LAMBDA * SIN ( U + U**2 + U**3 ) = 0 ! ! with boundary conditions ! ! U(0) = 0.0D+00 ! U(1) = 0.0D+00 ! ! U is approximated by piecewise polynomials whose coefficients are ! the unknowns U(1), ..., U(NVAR-1), and the value of LAMBDA is ! stored as U(NVAR). ! ! Options: ! ! OPTION Polynomials Continuity ! 1 linear 1 ! 2 cubic 1 ! 3 cubic 2 ! 4 quintic 1 ! 5 quintic 2 ! 6 quintic 3 ! ! All options use 8 intervals. ! ! Comments: ! ! The current program has zero as solution for all X(nvar). ! Must find bifurcation branch and jump on to it. ! Perhaps add X(nvar+1) a perturbation to right hand side. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 23 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Ivo Babuska, Werner Rheinboldt, ! Reliable Error Estimations and Mesh Adaptation for the Finite ! Element Method, ! in International Conference on Computational Methods ! in Nonlinear Mechanics, ! edited by John Oden, ! Elsevier, 1980, ! ISBN: 0444853820, ! LC: QA808.I57. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ), parameter :: nbco = 1 integer ( kind = 4 ), parameter :: nbcz = 1 integer ( kind = 4 ), parameter :: nint = 8 integer ( kind = 4 ), parameter :: maxpolys = 6 integer ( kind = 4 ) nvar real ( kind = 8 ) bcone(8) real ( kind = 8 ) bczero(8) real ( kind = 8 ) coef real ( kind = 8 ) dtdx real ( kind = 8 ) dtdxl real ( kind = 8 ) dtdxr real ( kind = 8 ) fx(nvar) real ( kind = 8 ) gcoef(8) real ( kind = 8 ) gpoint(8) real ( kind = 8 ) h2i real ( kind = 8 ) h2il real ( kind = 8 ) h2ir integer ( kind = 4 ) i integer ( kind = 4 ) ieqn integer ( kind = 4 ) option integer ( kind = 4 ) iskip integer ( kind = 4 ) ivar integer ( kind = 4 ) j integer ( kind = 4 ) k integer ( kind = 4 ) khi integer ( kind = 4 ) l integer ( kind = 4 ) lhil integer ( kind = 4 ) lhir integer ( kind = 4 ) lskip integer ( kind = 4 ) ncl integer ( kind = 4 ) ncr integer ( kind = 4 ) ndsum integer ( kind = 4 ) npsum integer ( kind = 4 ) nderiv integer ( kind = 4 ) npolys integer ( kind = 4 ) nvary real ( kind = 8 ) p12_theta real ( kind = 8 ) phi real ( kind = 8 ) pl(maxpolys) real ( kind = 8 ) pld(maxpolys) real ( kind = 8 ) psi real ( kind = 8 ) r8_mop real ( kind = 8 ) s real ( kind = 8 ) t real ( kind = 8 ) u real ( kind = 8 ) uprym real ( kind = 8 ) x(nvar) real ( kind = 8 ) xc real ( kind = 8 ) xl real ( kind = 8 ) xr bcone(1) = 0.0D+00 bczero(1) = 0.0D+00 fx(1:nvar-1) = 0.0D+00 if ( option == 1 ) then npolys = 2 nderiv = 1 else if ( option == 2 ) then npolys = 4 nderiv = 1 else if ( option == 3 ) then npolys = 4 nderiv = 2 else if ( option == 4 ) then npolys = 6 nderiv = 1 else if ( option == 5 ) then npolys = 6 nderiv = 2 else if ( option == 6 ) then npolys = 6 nderiv = 3 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P12_FUN - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if nvary = nint * npolys ! ! Get the Gauss quadrature rule. ! call p12_gauss8 ( gcoef, gpoint ) ! ! Set up the terms A * Y involving the bivariate form ! ! For each interval I: ! do i = 1, nint iskip = ( i - 1 ) * npolys xl = real ( i - 1 ) / real ( nint, kind = 8 ) xr = real ( i ) / real ( nint, kind = 8 ) dtdx = 2.0D+00 / ( xr - xl ) ! ! For each Gauss point, J, evaluate the integrand. ! do j = 1, 8 t = gpoint(j) coef = gcoef(j) * ( xr - xl ) / 2.0D+00 call p12_legendre_val ( t, dtdx, npolys, pl, pld ) u = 0.0D+00 uprym = 0.0D+00 do k = 1, npolys u = u + x(iskip+k) * pl(k) uprym = uprym + x(iskip+k) * pld(k) end do phi = - uprym psi = x(nvar) * sin ( u * ( 1.0D+00 + u * ( 1.0D+00 + u ) ) ) lskip = iskip ! ! Project onto each test function L. ! do l = 1, npolys ieqn = lskip + l fx(ieqn) = fx(ieqn) + coef * ( psi * pl(l) + phi * pld(l) ) end do lskip = lskip + npolys end do end do ! ! 2. Add the terms B * Z for the continuity of the test functions. ! ! For each interval I: ! do i = 1, nint if ( i == 1 ) then ncl = nvary else ncl = nvary + nbcz + ( i - 2 ) * nderiv end if ncr = nvary + nbcz + ( i - 1 ) * nderiv xl = real ( i - 1 ) / real ( nint, kind = 8 ) xr = real ( i ) / real ( nint, kind = 8 ) dtdx = 2.0D+00 / ( xr - xl ) ! ! Count conditions at the left endpoint, LHIL, and at right, LHIR. ! If we are in the first or last interval, one of ! these will be boundary conditions. ! if ( i == 1 ) then lhil = nbcz else lhil = nderiv end if if ( i == nint ) then lhir = nbco else lhir = nderiv end if ! ! For each test function PL(K): ! do k = 1, npolys s = r8_mop ( k + 1 ) ieqn = ( i - 1 ) * npolys + k ! ! Apply the boundary conditions. ! h2i = 1.0D+00 do l = 1, lhil s = - s ivar = ncl + l fx(ieqn) = fx(ieqn) + s * x(ivar) * h2i * p12_theta ( l, k ) h2i = h2i * dtdx end do h2i = 1.0D+00 do l = 1, lhir ivar = ncr + l fx(ieqn) = fx(ieqn) + x(ivar) * h2i * p12_theta ( l, k ) h2i = h2i * dtdx end do end do end do ! ! 3. Create the C * Y terms for U and its derivatives. ! One equation is generated for component and condition. ! npsum = 0 dtdxr = 0.0D+00 dtdxl = 0.0D+00 ! ! For each node: ! ndsum = nvary do i = 1, nint + 1 if ( 1 < i ) then xl = real ( i - 2 ) / real ( nint, kind = 8 ) end if xc = real ( i - 1 ) / real ( nint, kind = 8 ) if ( i < nint + 1 ) then xr = real ( i ) / real ( nint, kind = 8 ) end if if ( xc /= xl ) then dtdxl = 2.0D+00 / ( xc - xl ) end if if ( xr /= xc ) then dtdxr = 2.0D+00 / ( xr - xc ) end if h2il = 1.0D+00 h2ir = 1.0D+00 ! ! Count the conditions: ! if ( i == 1 ) then khi = nbcz else if ( i < nint + 1 ) then khi = nderiv else if ( i == nint + 1 ) then khi = nbco end if do k = 1, khi s = r8_mop ( k + 1 ) ! ! Set up the term from the left hand interval. ! ieqn = ndsum + k if ( i == 1 ) then fx(ieqn) = fx(ieqn) + bczero(k) else do l = 1, npolys ivar = npsum + l - npolys fx(ieqn) = fx(ieqn) + x(ivar) * h2il * p12_theta ( k, l ) end do end if ! ! Set up the term from the right hand interval. ! if ( i == nint + 1 ) then fx(ieqn) = fx(ieqn) - bcone(k) else do l = 1, npolys ivar = npsum + l s = - s fx(ieqn) = fx(ieqn) + s * x(ivar) * h2ir * p12_theta(k,l) end do end if h2il = h2il * dtdxl h2ir = h2ir * dtdxr end do ndsum = ndsum + khi npsum = npsum + npolys end do return end subroutine p12_gauss8 ( gcoef, gpoint ) !*****************************************************************************80 ! !! P12_GAUSS8 returns an 8 point Gauss quadrature rule. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, real ( kind = 8 ) GCOEF(8), the coefficients for the ! quadrature rule, normalized for the interval [-1,1]. ! ! Output, real ( kind = 8 ) GPOINT(8), the abscissas for the quadrature rule, ! normalized for the interval [-1,1]. ! implicit none real ( kind = 8 ) gcoef(8) real ( kind = 8 ) gpoint(8) gcoef(1) = 0.1012285363D+00 gcoef(2) = 0.2223810345D+00 gcoef(3) = 0.3137066459D+00 gcoef(4) = 0.3626837834D+00 gcoef(5) = 0.3626837834D+00 gcoef(6) = 0.3137066459D+00 gcoef(7) = 0.2223810345D+00 gcoef(8) = 0.1012285363D+00 gpoint(1) = - 0.9602898565D+00 gpoint(2) = - 0.7966664774D+00 gpoint(3) = - 0.5255324099D+00 gpoint(4) = - 0.1834346425D+00 gpoint(5) = 0.1834346425D+00 gpoint(6) = 0.5255324099D+00 gpoint(7) = 0.7966664774D+00 gpoint(8) = 0.9602898565D+00 return end subroutine p12_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P12_JAC evaluates the jacobian for problem 12. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 23 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ), parameter :: nbco = 1 integer ( kind = 4 ), parameter :: nbcz = 1 integer ( kind = 4 ), parameter :: nint = 8 integer ( kind = 4 ), parameter :: maxpolys = 6 integer ( kind = 4 ) nvar real ( kind = 8 ) dbcodt(8) real ( kind = 8 ) dbczdt(8) real ( kind = 8 ) coef real ( kind = 8 ) dtdx real ( kind = 8 ) gcoef(8) real ( kind = 8 ) gpoint(8) real ( kind = 8 ) h2i integer ( kind = 4 ) i integer ( kind = 4 ) ieqn integer ( kind = 4 ) option integer ( kind = 4 ) iskip integer ( kind = 4 ) ivar integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) k integer ( kind = 4 ) khil integer ( kind = 4 ) khir integer ( kind = 4 ) l integer ( kind = 4 ) lhil integer ( kind = 4 ) lhir integer ( kind = 4 ) n integer ( kind = 4 ) ncl integer ( kind = 4 ) ncr integer ( kind = 4 ) nderiv integer ( kind = 4 ) npolys integer ( kind = 4 ) npsum integer ( kind = 4 ) nvary real ( kind = 8 ) p12_theta real ( kind = 8 ) phipt real ( kind = 8 ) phipu real ( kind = 8 ) phipup real ( kind = 8 ) pl(maxpolys) real ( kind = 8 ) pld(maxpolys) real ( kind = 8 ) psipt real ( kind = 8 ) psipu real ( kind = 8 ) psipup real ( kind = 8 ) r8_mop real ( kind = 8 ) s real ( kind = 8 ) t real ( kind = 8 ) u real ( kind = 8 ) uprym real ( kind = 8 ) x(nvar) real ( kind = 8 ) xl real ( kind = 8 ) xr jac(1:nvar,1:nvar) = 0.0D+00 dbcodt(1) = 0.0D+00 dbczdt(1) = 0.0D+00 if ( option == 1 ) then npolys = 2 nderiv = 1 else if ( option == 2 ) then npolys = 4 nderiv = 1 else if ( option == 3 ) then npolys = 4 nderiv = 2 else if ( option == 4 ) then npolys = 6 nderiv = 1 else if ( option == 5 ) then npolys = 6 nderiv = 2 else if ( option == 6 ) then npolys = 6 nderiv = 3 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P12_JAC - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if nvary = nint * npolys ! ! Get the Gauss quadrature rule. ! call p12_gauss8 ( gcoef, gpoint ) ! ! 1. Set up the terms from the bivariate form A * Y: ! do i = 1, nint iskip = ( i - 1 ) * npolys xl = real ( i - 1 ) / real ( nint, kind = 8 ) xr = real ( i ) / real ( nint, kind = 8 ) dtdx = 2.0D+00 / ( xr - xl ) ! ! For each Gauss point in the interval: ! do j = 1, 8 t = gpoint(j) coef = gcoef(j) * ( xr - xl ) / 2.0D+00 call p12_legendre_val ( t, dtdx, npolys, pl, pld ) u = 0.0D+00 uprym = 0.0D+00 do k = 1, npolys u = u + x(iskip+k) * pl(k) uprym = uprym + x(iskip+k) * pld(k) end do phipu = 0.0D+00 phipup = - 1.0D+00 phipt = 0.0D+00 psipu = x(nvar) * ( 1.0D+00 + u * ( 2.0D+00 + 3.0D+00 * u ) ) & * cos ( u * ( 1.0D+00 + u * ( 1.0D+00 + u ) ) ) psipup = 0.0D+00 psipt = sin ( u * ( 1.0D+00 + u * ( 1.0D+00 + u ) ) ) ! ! For each Legendre polynomial coefficient: ! do l = 1, npolys ieqn = iskip + l jac(ieqn,nvar) = jac(ieqn,nvar) + coef * ( psipt * pl(l) + & phipt * pld(l) ) ! ! For each Y-coefficient of U: ! do n = 1, npolys ivar = npolys * ( i - 1 ) + n jac(ieqn,ivar) = jac(ieqn,ivar) + coef * ( & ( psipu * pl(n) + psipup * pld(n) ) * pl(l) & + ( phipu * pl(n) + phipup * pld(n) ) * pld(l) ) end do end do end do end do ! ! 2. Add the terms involving the continuity of the test functions ! which are the terms B * Z in F = A * Y + B * Z. ! do i = 1, nint if ( i == 1 ) then ncl = nvary else ncl = nvary + nbcz + ( i - 2 ) * nderiv end if ncr = nvary + nbcz + ( i - 1 ) * nderiv xl = real ( i - 1 ) / real ( nint, kind = 8 ) xr = real ( i ) / real ( nint, kind = 8 ) dtdx = 2.0D+00 / ( xr - xl ) ! ! For the polynomials used in approximating each U, ! count conditions at left endpoint, LHIL, and at right, LHIR. ! if ( i == 1 ) then lhil = nbcz else lhil = nderiv end if if ( i == nint ) then lhir = nbco else lhir = nderiv end if ! ! For each test function PL(K). ! do k = 1, npolys s = r8_mop ( k + 1 ) ieqn = ( i - 1 ) * npolys + k ! ! Consider the conditions: ! h2i = 1.0D+00 do l = 1, lhil s = - s ivar = ncl + l jac(ieqn,ivar) = s * h2i * p12_theta ( l, k ) h2i = h2i * dtdx end do ! ! Evaluate contribution from right endpoint. ! h2i = 1.0D+00 do l = 1, lhir ivar = ncr + l jac(ieqn,ivar) = h2i * p12_theta ( l, k ) h2i = h2i * dtdx end do end do end do ! ! 3. Create the terms for the U functions and their derivatives ! the matrix terms C * Y. ! do i = 1, nint if ( i == 1 ) then ncl = nvary else ncl = nvary + nbcz + ( i - 2 ) * nderiv end if ncr = nvary + nbcz + ( i - 1 ) * nderiv npsum = ( i - 1 ) * npolys xl = real ( i - 1 ) / real ( nint, kind = 8 ) xr = real ( i ) / real ( nint, kind = 8 ) dtdx = 2.0D+00 / ( xr - xl ) h2i = 1.0D+00 ! ! Count the conditions: ! if ( i == 1 ) then khil = nbcz else khil = nderiv end if ! ! Left hand term: ! do k = 1, khil ieqn = ncl + k if ( i == 1 ) then jac(ieqn,nvar) = dbczdt(k) end if s = r8_mop ( k + 1 ) do l = 1, npolys ivar = npsum + l s = - s jac(ieqn,ivar) = s * h2i * p12_theta ( k, l ) end do h2i = h2i * dtdx end do ncl = ncl + khil ! ! Right hand term: ! h2i = 1.0D+00 if ( i == nint ) then khir = nbco else khir = nderiv end if do k = 1, khir ieqn = ncr + k if ( i == nint ) then jac(ieqn,nvar) = - dbcodt(k) else jac(ieqn,nvar) = 0.0D+00 end if do l = 1, npolys ivar = npsum + l jac(ieqn,ivar) = h2i * p12_theta ( k, l ) end do h2i = h2i * dtdx end do ncr = ncr + khir npsum = npsum + npolys end do return end subroutine p12_legendre_val ( t, dtdx, npolys, pl, pld ) !*****************************************************************************80 ! !! P12_LEGENDRE_VAL evaluates the Legendre polynomials and derivatives. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) T, the argument of the Legendre polynomials, in ! the normalized interval [-1,1]. ! ! Input, real ( kind = 8 ) DTDX, the value of the quantity dTdX at the point ! X. In the most common case, this is simply the relationship ! between the width of the normalized T interval (2), and the ! width of the X interval to which the Legendre polynomial ! arguments have been mapped. DTDX is needed so that the ! computed values PLD can be converted from dPL/dT to dPL/dX. ! ! Input, integer ( kind = 4 ) NPOLYS, the number of Legendre polynomials to ! evaluate. If NPOLYS is 1, then only the constant polynomial ! is evaluated, NPOLYS = 2 means the constant and linear, and so on. ! ! Output, real ( kind = 8 ) PL(NPOLYS), PLD(NPOLYS), the values of PL(X) ! and dPL(X)/dX at the point X which has normalized coordinate T. ! implicit none integer ( kind = 4 ) npolys real ( kind = 8 ) a real ( kind = 8 ) dtdx integer ( kind = 4 ) i real ( kind = 8 ) pl(npolys) real ( kind = 8 ) pld(npolys) real ( kind = 8 ) t if ( 1 <= npolys ) then pl(1) = 1.0D+00 pld(1) = 0.0D+00 end if if ( 2 <= npolys ) then pl(2) = t pld(2) = 1.0D+00 end if a = 0.0D+00 do i = 3, npolys a = a + 1.0D+00 pl(i) = ( ( 2.0D+00 * a + 1.0D+00 ) * t * pl(i-1) - a * pl(i-2) ) & / ( a + 1.0D+00 ) pld(i) = ( ( 2.0D+00 * a + 1.0D+00 ) * ( t * pld(i-1) + pl(i-1) ) & - a * pld(i-2) ) / ( a + 1.0D+00 ) end do pld(1:npolys) = dtdx * pld(1:npolys) return end subroutine p12_nvar ( option, nvar ) !*****************************************************************************80 ! !! P12_NVAR sets the number of variables for problem 12. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nbco integer ( kind = 4 ) nbcz integer ( kind = 4 ) nderiv integer ( kind = 4 ) nint integer ( kind = 4 ) npolys integer ( kind = 4 ) nvar integer ( kind = 4 ) nvary integer ( kind = 4 ) nvarz if ( option == 1 ) then npolys = 2 nderiv = 1 else if ( option == 2 ) then npolys = 4 nderiv = 1 else if ( option == 3 ) then npolys = 4 nderiv = 2 else if ( option == 4 ) then npolys = 6 nderiv = 1 else if ( option == 5 ) then npolys = 6 nderiv = 2 else if ( option == 6 ) then npolys = 6 nderiv = 3 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P12_NVAR - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if nint = 8 nvary = nint * npolys nbcz = 1 nbco = 1 nvarz = nbcz + ( nint - 1 ) * nderiv + nbco nvar = nvary + nvarz + 1 return end subroutine p12_option_num ( option_num ) !*****************************************************************************80 ! !! P12_OPTION_NUM returns the number of options for problem 12. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 6 return end subroutine p12_start ( option, nvar, x ) !*****************************************************************************80 ! !! P12_START returns a starting point for problem 12. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 return end subroutine p12_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P12_STEPSIZE returns step sizes for problem 12. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 2.000D+00 hmin = 0.001D+00 hmax = 10.000D+00 return end function p12_theta ( i, j ) !*****************************************************************************80 ! !! P12_THETA is a utility routine used in problem 12. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 21 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) I, J, the indices of THETA. ! ! Output, real ( kind = 8 ) P12_THETA, the value of THETA(I,J). ! implicit none integer ( kind = 4 ), parameter :: nmax = 10 integer ( kind = 4 ) i integer ( kind = 4 ) j real ( kind = 8 ) p12_theta real ( kind = 8 ), save, dimension(nmax,nmax) :: theta data theta / & 1.0, 0.0, 0.0, 0.0, 0.0, & 0.0, 0.0, 0.0, 0.0, 0.0, & 1.0, 1.0, 0.0, 0.0, 0.0, & 0.0, 0.0, 0.0, 0.0, 0.0, & 1.0, 3.0, 3.0, 0.0, 0.0, & 0.0, 0.0, 0.0, 0.0, 0.0, & 1.0, 6.0, 15.0, 15.0, 0.0, & 0.0, 0.0, 0.0, 0.0, 0.0, & 1.0, 10.0, 45.0, 105.0, 105.0, & 0.0, 0.0, 0.0, 0.0, 0.0, & 1.0, 15.0, 105.0, 420.0, 945.0, & 945.0, 0.0, 0.0, 0.0, 0.0, & 1.0, 21.0, 210.0, 1260.0, 4725.0, & 10395.0, 10395.0, 0.0, 0.0, 0.0, & 1.0, 28.0, 378.0, 3150.0, 17325.0, & 62370.0, 135135.0, 135135.0, 0.0, 0.0, & 1.0, 36.0, 630.0, 6930.0, 51975.0, & 270270.0, 945945.0, 2027025.0, 2027025.0, 0.0, & 1.0, 45.0, 990.0, 13860.0, 135135.0, & 945945.0, 4729725.0, 16216200.0,34459425.0,34459425.0 / if ( i < 1 .or. nmax < i .or. j < 1 .or. nmax < j ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P12_THETA - Fatal error!' write ( *, '(a)' ) ' I or J is out of bounds.' stop end if p12_theta = theta ( i, j ) return end subroutine p12_title ( option, title ) !*****************************************************************************80 ! !! P12_TITLE sets the title for problem 12. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Materially nonlinear problem, NPOLYS = 2, NDERIV = 1.' else if ( option == 2 ) then title = 'Materially nonlinear problem, NPOLYS = 4, NDERIV = 1.' else if ( option == 3 ) then title = 'Materially nonlinear problem, NPOLYS = 4, NDERIV = 2.' else if ( option == 4 ) then title = 'Materially nonlinear problem, NPOLYS = 6, NDERIV = 1.' else if ( option == 5 ) then title = 'Materially nonlinear problem, NPOLYS = 6, NDERIV = 2.' else if ( option == 6 ) then title = 'Materially nonlinear problem, NPOLYS = 6, NDERIV = 3.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P12_TITLE - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p13_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P13_FUN evaluates the function for problem 13. ! ! Discussion: ! ! Simpson's mildly nonlinear boundary value problem. ! ! The continuous problem is defined on the unit square, ! and has the form: ! ! - Laplacian ( U(X,Y) ) = LAMBDA * F ( U(X,Y) ) ! ! for points within the unit square, and boundary condition ! ! U(X,Y) = 0. ! ! The continuous problem is discretized with a uniform M by M ! mesh of point in the interior. Let DEL9 be the nine point ! discrete Laplacian operator, and DEL5 the five point discrete ! Laplacian operator. Then the discrete problem has the form: ! ! DEL9 U + lambda * ( F(U) + H**2 * DEL5 ( F(U) ) / 12 ) = 0.0D+00 ! ! where H is the mesh spacing. ! ! The options allow a choice of M and the right hand side function F. ! ! OPTION M NVAR F(U) ! ! 1 8 65 exp ( U ) ! 2 8 65 ( 100 + 100 * U + 51 * U**2 ) / ( 100 + U**2 ) ! 3 12 145 exp ( U ) ! 4 12 145 ( 100 + 100 * U + 51 * U**2 ) / ( 100 + U**2 ) ! 5 16 257 exp ( U ) ! 6 16 257 ( 100 + 100 * U + 51 * U**2 ) / ( 100 + U**2 ) ! ! Melhem lists a limit point in LAMBDA for each of the option cases ! above. Letting U* be the value of the computed solution at the ! center point of the grid, we have: ! ! OPTION Lambda U* ! ! 1 6.807504 1.391598 ! 2 7.980356 2.272364 ! 3 6.808004 1.391657 ! 4 7.981426 2.273045 ! 5 6.808087 1.391656 ! 6 7.981605 2.273159 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 16 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Rami Melhem, Werner Rheinboldt, ! A Comparison of Methods for Determining Turning Points of ! Nonlinear Equations, ! Computing, ! Volume 29, Number 3, September 1982, pages 201-226. ! ! Bruce Simpson, ! A Method for the Numerical Determination of Bifurcation ! States of Nonlinear Systems of Equations, ! SIAM Journal on Numerical Analysis, ! Volume 12, Number 3, June 1975, pages 439-451. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) option real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) x(nvar) ! ! Compute M, the order of the square grid, such that M*M = NVAR-1. ! m = nint ( sqrt ( real ( nvar - 1, kind = 8 ) ) ) lambda = x(nvar) call p13_fx2 ( option, m, x, lambda, fx ) return end subroutine p13_fx2 ( option, m, u, lambda, fx ) !*****************************************************************************80 ! !! P13_FX2 computes the function by recasting it on a square grid. ! ! Discussion: ! ! For M = 4, there are M*M = 16 U variables plus LAMBDA. ! ! The ordering of the U variables is suggested by the diagram, in which ! "0" indicates a point where U is zero, and a nonzero value indicates ! the index in the vector U of the corresponding value: ! ! | ! 1.0 0 0 0 0 0 0 ! | 0 13 14 15 16 0 ! | 0 9 10 11 12 0 ! Y 0 5 6 7 8 0 ! | 0 1 2 3 4 0 ! 0.0 0 0 0 0 0 0 ! | ! +--0.0------X----------1.0---> ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) M, the number of grid points along a side of ! the square. ! ! Input, real ( kind = 8 ) U(M,M), the value of the grid function at the ! grid points. ! ! Input, real ( kind = 8 ) LAMBDA, the value of the parameter. ! ! Output, real ( kind = 8 ) FX(M,M), the value of the function. ! implicit none integer ( kind = 4 ) m real ( kind = 8 ) del5f real ( kind = 8 ) del9u real ( kind = 8 ) fc real ( kind = 8 ) fe real ( kind = 8 ) fn real ( kind = 8 ) fs real ( kind = 8 ) fw real ( kind = 8 ) fx(m,m) real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) lambda real ( kind = 8 ) p13_gx real ( kind = 8 ) u(m,m) real ( kind = 8 ) uc real ( kind = 8 ) ue real ( kind = 8 ) un real ( kind = 8 ) une real ( kind = 8 ) unw real ( kind = 8 ) us real ( kind = 8 ) use real ( kind = 8 ) usw real ( kind = 8 ) uw h = 1.0D+00 / real ( m + 1, kind = 8 ) do i = 1, m do j = 1, m ! ! Evaluate the solution on the grid: ! ! UNW-UN--UNE ! | | | ! UW--UC--UE ! | | | ! USW-US--USE ! uc = u(i,j) if ( i < m ) then un = u(i+1,j) else un = 0.0D+00 end if if ( 1 < i ) then us = u(i-1,j) else us = 0.0D+00 end if if ( j < m ) then ue = u(i,j+1) else ue = 0.0D+00 end if if ( 1 < j ) then uw = u(i,j-1) else uw = 0.0D+00 end if if ( 1 < i .and. 1 < j ) then usw = u(i-1,j-1) else usw = 0.0D+00 end if if ( 1 < i .and. j < m ) then use = u(i-1,j+1) else use = 0.0D+00 end if if ( i < m .and. 1 < j ) then unw = u(i+1,j-1) else unw = 0.0D+00 end if if ( i < m .and. j < m ) then une = u(i+1,j+1) else une = 0.0D+00 end if ! ! Evaluate the right hand side on the grid. ! ! FN ! | ! FW-FC-FE ! | ! FS ! fc = p13_gx ( option, uc ) fn = p13_gx ( option, un ) fs = p13_gx ( option, us ) fe = p13_gx ( option, ue ) fw = p13_gx ( option, uw ) ! ! Compute the 9 point approximation to Laplacian U. ! del9u = ( - 20.0D+00 * uc + 4.0D+00 * ( un + us + ue + uw ) & + une + unw + use + usw ) / ( 6.0D+00 * h * h ) del5f = fc + h * h * ( - 4.0D+00 * fc + fn + fs + fe + fw ) / 12.0D+00 fx(i,j) = del9u + lambda * del5f end do end do return end function p13_gp ( option, u ) !*****************************************************************************80 ! !! P13_GP evaluates the derivative of the right hand side function. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, real ( kind = 8 ) U, the value of the argument. ! ! Output, real ( kind = 8 ) P13_GP, the derivative of the right hand side ! at U. ! implicit none integer ( kind = 4 ) option real ( kind = 8 ) p13_gp real ( kind = 8 ) u if ( option == 1 .or. option == 3 .or. option == 5 ) then p13_gp = exp ( u ) else if ( option == 2 .or. option == 4 .or. option == 6 ) then p13_gp = ( 1.0D+00 + u - 0.01D+00 * u * u ) & / ( 1.0D+00 + 0.01D+00 * u * u )**2 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P13_GP - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end function p13_gx ( option, u ) !*****************************************************************************80 ! !! P13_GX evaluates the right hand side function. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, real ( kind = 8 ) U, the value of the argument. ! ! Output, real ( kind = 8 ) P13_GX, the right hand side function at U. ! implicit none integer ( kind = 4 ) option real ( kind = 8 ) p13_gx real ( kind = 8 ) u if ( option == 1 .or. option == 3 .or. option == 5 ) then p13_gx = exp ( u ) else if ( option == 2 .or. option == 4 .or. option == 6 ) then p13_gx = ( 100.0D+00 + 100.0D+00 * u + 51.0D+00 * u * u ) & / ( 100.0D+00 + u * u ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P13_GX - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end subroutine p13_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P13_JAC evaluates the jacobian for problem 13. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 m = nint ( sqrt ( real ( nvar - 1, kind = 8 ) ) ) lambda = x(nvar) call p13_jac2 ( option, m, nvar, lambda, x, jac ) return end subroutine p13_jac2 ( option, m, nvar, lambda, u, jac ) !*****************************************************************************80 ! !! P13_JAC2 computes the jacobian by recasting it on a square grid. ! ! Discussion: ! ! Actually, to stave off insanity, we only "recast" the variables into ! a 2D array that corresponds to the spatial ordering of the grid. ! We leave the jacobian in its original arrangement, which assumes ! a linear ordering of variables and equations, and we simply ! compute the equation and variable indices of the jacobian when ! we are ready to put entries into it. This approach seems to produce ! a smaller amount of cosmic grief than the alternatives. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) M, the number of grid points on a side ! of the square. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) LAMBDA, the value of the parameter. ! ! Input, real ( kind = 8 ) U(M,M), the value of the grid function. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) nvar real ( kind = 8 ) del5f real ( kind = 8 ) fc real ( kind = 8 ) fcp real ( kind = 8 ) fe real ( kind = 8 ) fep real ( kind = 8 ) fn real ( kind = 8 ) fnp real ( kind = 8 ) fs real ( kind = 8 ) fsp real ( kind = 8 ) fw real ( kind = 8 ) fwp real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) ieqn integer ( kind = 4 ) option integer ( kind = 4 ) ivar integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) lambda real ( kind = 8 ) p13_gp real ( kind = 8 ) p13_gx real ( kind = 8 ) u(m,m) real ( kind = 8 ) uc real ( kind = 8 ) ue real ( kind = 8 ) un real ( kind = 8 ) us real ( kind = 8 ) uw h = 1.0D+00 / real ( m + 1, kind = 8 ) ieqn = 0 do i = 1, m do j = 1, m ieqn = ( j - 1 ) * m + i uc = u(i,j) if ( i < m ) then un = u(i+1,j) else un = 0.0D+00 end if if ( 1 < i ) then us = u(i-1,j) else us = 0.0D+00 end if if ( j < m ) then ue = u(i,j+1) else ue = 0.0D+00 end if if ( 1 < j ) then uw = u(i,j-1) else uw = 0.0D+00 end if fc = p13_gx ( option, uc ) fn = p13_gx ( option, un ) fs = p13_gx ( option, us ) fe = p13_gx ( option, ue ) fw = p13_gx ( option, uw ) del5f = fc + h * h * ( - 4.0D+00 * fc + fn + fs + fe + fw ) / 12.0D+00 fcp = p13_gp ( option, uc ) fnp = p13_gp ( option, un ) fsp = p13_gp ( option, us ) fep = p13_gp ( option, ue ) fwp = p13_gp ( option, uw ) ivar = ( j - 1 ) * m + i jac(ieqn,ivar) = - 20.0D+00 / ( 6.0D+00 * h * h ) & + lambda * ( fcp - 4.0D+00 * h * h * fcp / 12.0D+00 ) if ( i < m ) then ivar = ( j - 1 ) * m + i + 1 jac(ieqn,ivar) = 4.0D+00 / ( 6.0D+00 * h * h ) & + lambda * h * h * fnp / 12.0D+00 end if if ( 1 < i ) then ivar = ( j - 1 ) * m + i - 1 jac(ieqn,ivar) = 4.0D+00 / ( 6.0D+00 * h * h ) & + lambda * h * h * fsp / 12.0D+00 end if if ( j < m ) then ivar = j * m + i jac(ieqn,ivar) = 4.0D+00 / ( 6.0D+00 * h * h ) & + lambda * h * h * fep / 12.0D+00 end if if ( 1 < j ) then ivar = ( j - 2 ) * m + i jac(ieqn,ivar) = 4.0D+00 / ( 6.0D+00 * h * h ) & + lambda * h * h * fwp / 12.0D+00 end if if ( 1 < i .and. 1 < j ) then ivar = ( j - 2 ) * m + i - 1 jac(ieqn,ivar) = 1.0D+00 / ( 6.0D+00 * h * h ) end if if ( 1 < i .and. j < m ) then ivar = j * m + i - 1 jac(ieqn,ivar) = 1.0D+00 / ( 6.0D+00 * h * h ) end if if ( i < m .and. 1 < j ) then ivar = ( j - 2 ) * m + i + 1 jac(ieqn,ivar) = 1.0D+00 / ( 6.0D+00 * h * h ) end if if ( i < m .and. j < m ) then ivar = j * m + i + 1 jac(ieqn,ivar) = 1.0D+00 / ( 6.0D+00 * h * h ) end if ivar = nvar jac(ieqn,nvar) = del5f end do end do return end subroutine p13_nvar ( option, nvar ) !*****************************************************************************80 ! !! P13_NVAR sets the number of variables for problem 13. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) m integer ( kind = 4 ) nvar if ( option == 1 ) then m = 8 else if ( option == 2 ) then m = 8 else if ( option == 3 ) then m = 12 else if ( option == 4 ) then m = 12 else if ( option == 5 ) then m = 16 else if ( option == 6 ) then m = 16 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P13_NVAR - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if nvar = m * m + 1 return end subroutine p13_option_num ( option_num ) !*****************************************************************************80 ! !! P13_OPTION_NUM returns the number of options for problem 13. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 6 return end subroutine p13_start ( option, nvar, x ) !*****************************************************************************80 ! !! P13_START returns a starting point for problem 13. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 return end subroutine p13_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P13_STEPSIZE returns step sizes for problem 13. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 2.000D+00 hmin = 0.001D+00 hmax = 10.000D+00 return end subroutine p13_title ( option, title ) !*****************************************************************************80 ! !! P13_TITLE sets the title for problem 13. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Simpson''s BVP, F(U) = EXP(U), M = 8.' else if ( option == 2 ) then title = 'Simpson''s BVP, F(U) = function 2, M = 8.' else if ( option == 3 ) then title = 'Simpson''s BVP, F(U) = EXP(U), M = 12.' else if ( option == 4 ) then title = 'Simpson''s BVP, F(U) = function 2, M = 12.' else if ( option == 5 ) then title = 'Simpson''s BVP, F(U) = EXP(U), M = 16.' else if ( option == 6 ) then title = 'Simpson''s BVP, F(U) = function 2, M = 16.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P13_TITLE - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option = ', option stop end if return end function p14_fu ( lambda, u ) !*****************************************************************************80 ! !! P14_FU computes the auxilliary function F(LAMBDA,U). ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) LAMBDA, U, the arguments of the function. ! ! Output, real ( kind = 8 ) P14_FU, the value of the function. ! implicit none real ( kind = 8 ), parameter :: alpha = 0.1D+00 real ( kind = 8 ) lambda real ( kind = 8 ) p14_fu real ( kind = 8 ) u p14_fu = 1.0D+00 + lambda / ( u + alpha )**2 return end function p14_fudl ( u ) !*****************************************************************************80 ! !! P14_FUDL computes d F(LAMBDA,U) / d LAMBDA. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) U, the argument of the function. ! ! Output, real ( kind = 8 ) P14_FUDL, the value of the derivative ! of the function with respect to LAMBDA. ! implicit none real ( kind = 8 ), parameter :: alpha = 0.1D+00 real ( kind = 8 ) p14_fudl real ( kind = 8 ) u p14_fudl = 1.0D+00 / ( u + alpha )**2 return end function p14_fudu ( lambda, u ) !*****************************************************************************80 ! !! P14_FUDU computes d F(LAMBDA,U) / d U ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) LAMBDA, U, the arguments of the function. ! ! Output, real ( kind = 8 ) P14_FUDU, the value of the derivative ! of the function with respect to U. ! implicit none real ( kind = 8 ), parameter :: alpha = 0.1D+00 real ( kind = 8 ) lambda real ( kind = 8 ) p14_fudu real ( kind = 8 ) u p14_fudu = - 2.0D+00 * lambda / ( u + alpha )**3 return end subroutine p14_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P14_FUN computes the function for problem 14. ! ! Discussion: ! ! Keller's boundary value problem. ! ! The continuous problem is a two point boundary value problem ! describing a diffusion-kinetics system, of the form: ! ! -d/dt ( t * t * F(U) * dU/dt ) + t * t * G(U) = 0 ! ! where F(U) and G(U) are given functions, ! with boundary conditions ! ! dU/dt(0) = 0, ! U(1) = 1. ! ! A finite difference approximation to this continous problem ! is used. ! ! M points T(I) are used. With a spacing of H=1/(M-2), the points ! are set so that ! ! T(1)=-H, T(2)=0, T(3)=H, ..., T(M)=1.0D+00 ! ! First equation: ! ! U(3) - U(1) = 0.0D+00 ! ! Equations I = 2 through I = M-1 ! ! TL**2 * F(UL) * ( U(I) - U(I-1) ) + ! TR**2 * F(UR) * ( U(I) - U(I+1) ) + ! H**2 * T**2 * G(U) = 0.0D+00 ! ! with ! ! T = T(I) = ( I - 2 ) * H ! U = U(I) ! TL = 0.5 * ( T(I-1) + T(I) ) ! UL = 0.5 * ( U(I-1) + U(I) ) ! TR = 0.5 * ( T(I) + T(I+1) ) ! UR = 0.5 * ( U(I) + U(I+1) ) ! ! and the diffusion function F(U) ! ! F(U) = 1 + LAMBDA / ( U + ALPHA )**2 ! ! and ! ! G(U) = U / ( BETA * ( U + GAMMA ) ) ! ! Equation M-1: ! ! U(M) = 1.0D+00 ! ! For this version ALPHA = BETA = GAMMA = 0.1. ! ! The only choice for options is ! ! OPTION = 1: ! IT = NVAR, ! XIT = 1.0, ! LIM = NVAR. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Herbert Keller, ! Numerical Methods for Two-point Boundary Value Problems, ! Dover, 1992, ! ISBN: 0486669254, ! LC: QA372.K42. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) p14_fu real ( kind = 8 ) p14_gu real ( kind = 8 ) t real ( kind = 8 ) tl real ( kind = 8 ) tr real ( kind = 8 ) ul real ( kind = 8 ) ur real ( kind = 8 ) x(nvar) m = nvar - 1 h = 1.0D+00 / real ( m - 2, kind = 8 ) lambda = x(nvar) fx(1) = x(3) - x(1) do i = 2, m - 1 t = ( i - 2 ) * h tl = ( real ( i, kind = 8 ) - 2.5D+00 ) * h tr = ( real ( i, kind = 8 ) - 1.5D+00 ) * h ul = 0.5D+00 * ( x(i-1) + x(i) ) ur = 0.5D+00 * ( x(i) + x(i+1) ) fx(i) = ( x(i) - x(i-1) ) * tl * tl * p14_fu ( lambda, ul ) & + ( x(i) - x(i+1) ) * tr * tr * p14_fu ( lambda, ur ) & + h * h * t * t * p14_gu ( x(i) ) end do fx(m) = x(m) - 1.0D+00 return end function p14_gu ( u ) !*****************************************************************************80 ! !! P14_GU computes the auxilliary function G(U). ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) U, the argument of the function. ! ! Output, real ( kind = 8 ) P14_GU, the value of the function. ! implicit none real ( kind = 8 ), parameter :: beta = 0.1D+00 real ( kind = 8 ), parameter :: gamma = 0.1D+00 real ( kind = 8 ) p14_gu real ( kind = 8 ) u p14_gu = u / ( beta * ( u + gamma ) ) return end function p14_gudu ( u ) !*****************************************************************************80 ! !! P14_GUDU computes d G(U) / d U. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 19 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) U, the argument of the function. ! ! Output, real ( kind = 8 ) P14_GUDU, the value of the function. ! implicit none real ( kind = 8 ), parameter :: beta = 0.1D+00 real ( kind = 8 ), parameter :: gamma = 0.1D+00 real ( kind = 8 ) p14_gudu real ( kind = 8 ) u p14_gudu = gamma / ( beta * ( u + gamma )**2 ) return end subroutine p14_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P14_JAC computes the jacobian of problem 14. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 17 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) p14_fu real ( kind = 8 ) p14_fudl real ( kind = 8 ) p14_fudu real ( kind = 8 ) p14_gudu real ( kind = 8 ) t real ( kind = 8 ) tl real ( kind = 8 ) tr real ( kind = 8 ) ul real ( kind = 8 ) ur real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 m = nvar - 1 h = 1.0D+00 / real ( m - 2, kind = 8 ) lambda = x(nvar) ! ! First equation. ! jac(1,1) = - 1.0D+00 jac(1,3) = 1.0D+00 ! ! Intermediate equations. ! do i = 2, m - 1 t = ( i - 2 ) * h tl = ( real ( i, kind = 8 ) - 2.5D+00 ) * h tr = ( real ( i, kind = 8 ) - 1.5D+00 ) * h ul = 0.5D+00 * ( x(i-1) + x(i) ) ur = 0.5D+00 * ( x(i) + x(i+1) ) jac(i,i) = tl * tl * p14_fu ( lambda, ul ) & + ( x(i) - x(i-1) ) * tl * tl * p14_fudu ( lambda, ul ) * 0.5D+00 & + tr * tr * p14_fu ( lambda, ur ) & + ( x(i) - x(i+1) ) * tr * tr * p14_fudu ( lambda, ur ) * 0.5D+00 & + h * h * t * t * p14_gudu ( x(i) ) jac(i,i-1) = - tl * tl * p14_fu ( lambda, ul ) & + ( x(i) - x(i-1) ) * tl * tl * p14_fudu ( lambda, ul ) * 0.5D+00 jac(i,i+1) = - tr * tr * p14_fu ( lambda, ur ) & + ( x(i) - x(i+1) ) * tr * tr * p14_fudu ( lambda, ur ) * 0.5D+00 jac(i,nvar) = ( x(i) - x(i-1) ) * tl * tl * p14_fudl ( ul ) & + ( x(i) - x(i+1) ) * tr * tr * p14_fudl ( ur ) end do ! ! Last equation. ! jac(m,m) = 1.0D+00 return end subroutine p14_nvar ( option, nvar ) !*****************************************************************************80 ! !! P14_NVAR sets the number of variables for problem 14. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 18 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) m integer ( kind = 4 ) nvar m = 12 nvar = m + 1 return end subroutine p14_option_num ( option_num ) !*****************************************************************************80 ! !! P14_OPTION_NUM returns the number of options for problem 14. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 18 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p14_start ( option, nvar, x ) !*****************************************************************************80 ! !! P14_START returns a starting point for problem 14. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 29 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) m real ( kind = 8 ) x(nvar) if ( option == 1 ) then x(1) = 0.029742673007439D+00 x(2) = 0.029742673007439D+00 x(3) = 0.029742673007439D+00 x(4) = 0.039933250735582D+00 x(5) = 0.061866539016825D+00 x(6) = 0.101137641789028D+00 x(7) = 0.164623875371221D+00 x(8) = 0.258536575943466D+00 x(9) = 0.387217701462343D+00 x(10) = 0.553103336509555D+00 x(11) = 0.757271228030916D+00 x(12) = 1.000000000000000D+00 x(13) = 0.000000000000000D+00 else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P14_START - Fatal error!' write ( *, '(a,i8)' ) ' Unrecognized option value = ', option end if return end subroutine p14_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P14_STEPSIZE returns step sizes for problem 14. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 2.000D+00 hmin = 0.001D+00 hmax = 10.000D+00 return end subroutine p14_title ( option, title ) !*****************************************************************************80 ! !! P14_TITLE sets the title for problem 14. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 18 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'Keller''s BVP.' return end subroutine p15_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P15_FUN evaluates the function for problem 15. ! ! Title: ! ! The Trigger Circuit. ! ! Description: ! ! The current flow of a trigger circuit with an operational amplifier ! is modeled. The variables are voltages, with X(6) the output ! voltage and X(7) the input voltage. ! ! The function has the form ! ! F(X) = A * X + PHI ( X ) ! ! where A is a 6 by 7 matrix, and PHI is a nonlinear term, that is, ! ! F(I) = SUM ( 1 <= J <= 7 ) A(I,J) * X(J) + PHI ( X ) ! ! Options: ! ! Melhem lists the following limit points in X(7): ! ! ( 0.04936 0.54735 0.04944 0.04944 0.12920 1.16602 0.60185 ) ! ( 0.23577 0.66296 0.23759 0.23760 0.62083 9.60913 0.32286 ) ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 29 August 20008 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Rami Melhem, Werner Rheinboldt, ! A Comparison of Methods for Determining Turning Points of ! Nonlinear Equations, ! Computing, ! Volume 29, Number 3, September 1982, pages 201-226. ! ! Gerd Poenisch, Hubert Schwetlick, ! Computing Turning Points of Curves Implicitly Defined by Nonlinear ! Equations Depending on a Parameter, ! Computing, ! Volume 26, Number 2, June 1981, pages 107-121. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the point of evaluation. ! ! Input, real ( kind = 8 ) FX(NVAR-1), the function value. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) array(6,7) real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) x(nvar) ! ! Get the linear coefficients. ! call p15_gx ( array ) ! ! Compute the linear portion of the function. ! fx(1:nvar-1) = 0.0D+00 do i = 1, nvar - 1 do j = 1, nvar fx(i) = fx(i) + array(i,j) * x(j) end do end do ! ! Add the nonlinear terms. ! fx(2) = fx(2) + 5.6D-08 * ( exp ( 25.0D+00 * x(2) ) - 1.0D+00 ) fx(5) = fx(5) + 5.6D-08 * ( exp ( 25.0D+00 * x(5) ) - 1.0D+00 ) fx(6) = fx(6) - 7.65D+00 * atan ( 1962.0D+00 * ( x(3) - x(1) ) ) / 0.201D+00 return end subroutine p15_gx ( array ) !*****************************************************************************80 ! !! P15_GX returns the coefficients of the linear portion of the function. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 23 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, real ( kind = 8 ) ARRAY(6,7), the coefficients of the linear ! portion of the function, which are sums of the inverses of resistances. ! implicit none real ( kind = 8 ) array(6,7) integer ( kind = 4 ) i integer ( kind = 4 ) j real ( kind = 8 ), parameter :: s0 = 1.0D+00 / 10.0D+00 real ( kind = 8 ), parameter :: s1 = 1.0D+00 / 39.0D+00 real ( kind = 8 ), parameter :: s2 = 1.0D+00 / 51.0D+00 real ( kind = 8 ), parameter :: s3 = 1.0D+00 / 10.0D+00 real ( kind = 8 ), parameter :: s4 = 1.0D+00 / 25.5D+00 real ( kind = 8 ), parameter :: s5 = 1.0D+00 / 1.0D+00 real ( kind = 8 ), parameter :: s6 = 1.0D+00 / 0.62D+00 real ( kind = 8 ), parameter :: s7 = 1.0D+00 / 13.0D+00 real ( kind = 8 ), parameter :: s8 = 1.0D+00 / 0.201D+00 array(1:6,1:7) = 0.0D+00 array(1,1) = + s0 + s1 + s2 array(1,2) = - s1 array(1,3) = - s0 array(1,7) = - s2 array(2,1) = - s1 array(2,2) = + s1 + s2 array(2,6) = - s3 array(3,1) = - s0 array(3,3) = + s0 + s4 array(3,4) = - s4 array(4,3) = - s4 array(4,4) = + s4 + s5 + s6 array(4,5) = - s5 array(5,4) = - s5 array(5,5) = + s5 + s7 array(5,6) = - s7 array(6,2) = - s3 array(6,5) = - s7 array(6,6) = + s3 + s7 + s8 return end subroutine p15_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P15_JAC computes the jacobian for problem 15. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 21 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) array(6,7) real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) u real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 ! ! Get the coefficients of the linear part of the function. ! call p15_gx ( array ) jac(1:nvar-1,1:nvar) = array(1:nvar-1,1:nvar) ! ! Add the derivatives of the nonlinear part. ! jac(2,2) = jac(2,2) + 5.6D-08 * 25.0D+00 * exp ( 25.0D+00 * x(2) ) jac(5,5) = jac(5,5) + 5.6D-08 * 25.0D+00 * exp ( 25.0D+00 * x(5) ) u = 1962.0D+00 * ( x(3) - x(1) ) jac(6,1) = jac(6,1) + 7.65D+00 * 1962.0D+00 / ( 1.0D+00 + u * u ) / 0.201D+00 jac(6,3) = jac(6,3) - 7.65D+00 * 1962.0D+00 / ( 1.0D+00 + u * u ) / 0.201D+00 return end subroutine p15_nvar ( option, nvar ) !*****************************************************************************80 ! !! P15_NVAR sets the number of variables for problem 15. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 21 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 7 return end subroutine p15_option_num ( option_num ) !*****************************************************************************80 ! !! P15_OPTION_NUM returns the number of options for problem 15. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 21 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p15_start ( option, nvar, x ) !*****************************************************************************80 ! !! P15_START returns a starting point for problem 15. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 21 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 return end subroutine p15_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P15_STEPSIZE returns step sizes for problem 15. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.300D+00 hmin = 0.001D+00 hmax = 0.600D+00 return end subroutine p15_title ( option, title ) !*****************************************************************************80 ! !! P15_TITLE sets the title for problem 15. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'The Trigger Circuit.' return end subroutine p16_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P16_FUN evaluates the function for problem 16. ! ! Title: ! ! The Moore-Spence Chemical Reaction Integral Equation ! ! Description: ! ! The continuous equation describes the heat and mass transfer in a ! plate-shaped porous catalyst, and is of the form ! ! Y(S) = 1 + integral ( 0 <= T <= 1) K(S,T) * G(Y(T)) dT ! ! with ! ! K(S,T) = MAX ( S, T ) - 1 ! ! G(Y) = Y * EXP ( BETA * GAMMA * ( 1 - Y ) ! / ( 1 + BETA * ( 1 - Y ) ) ) ! ! with ! ! BETA = 0.4, ! GAMMA = 20.0. ! ! The integral equation is discretized using M equally spaced ! abscissas T(I) from 0 to 1, and applying the trapezoidal rule to ! compute the integrand. Finally, the integral is multiplied ! by a homotopy parameter LAMBDA so that the problem is easy ! to solve for LAMBDA = 0, while the solution for LAMBDA = 1 ! is the solution of the original problem. Thus: ! ! F(I) = Y(I) - 1 - LAMBDA * Trapezoid ( K(S(I),T())*G(Y(T())), T() ). ! ! Options: ! ! The solution for LAMBDA = 1 is desired. ! ! With NVAR = 17, Melhem lists the limit points in LAMBDA: ! ! LAMBDA = 0.1375390, x(16) = 0.8524311, ! LAMBDA = 0.07791579, x(16) = 0.4657826. ! ! Computational results with this program are: ! ! LAMBDA = 0.1286312, x(16) = 0.8977113, ! LAMBDA = 0.0926850, x(16) = 0.2956740. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 23 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Rami Melhem, Werner Rheinboldt, ! A Comparison of Methods for Determining Turning Points of ! Nonlinear Equations, ! Computing, ! Volume 29, Number 3, September 1982, pages 201-226. ! ! Gerald Moore, Alastair Spence, ! The Calculation of Turning Points of Nonlinear Equations, ! SIAM Journal on Numerical Analysis, ! Volume 17, Number 4, August 1980, pages 567-576. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at U. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) arg real ( kind = 8 ), parameter :: beta = 0.4D+00 real ( kind = 8 ) factor real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ), parameter :: gamma = 20.0D+00 real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) s real ( kind = 8 ) t real ( kind = 8 ) trapezoid real ( kind = 8 ) x(nvar) lambda = x(nvar) m = nvar - 1 h = 1.0D+00 / real ( m - 1, kind = 8 ) do i = 1, m s = h * ( i - 1 ) trapezoid = 0.0D+00 do j = 1, m t = h * ( j - 1 ) arg = beta * gamma * ( 1.0D+00 - x(j) ) & / ( 1.0D+00 + beta * ( 1.0D+00 - x(j) ) ) if ( j == 1 ) then factor = 0.5D+00 else if ( j < m - 1 ) then factor = 1.0D+00 else if ( j == m ) then factor = 0.5D+00 end if trapezoid = trapezoid + h * factor * x(j) * exp ( arg ) * & ( max ( s, t ) - 1.0D+00 ) end do fx(i) = x(i) - 1.0D+00 - lambda * trapezoid end do return end subroutine p16_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P16_JAC computes the jacobian for problem 16. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) U(NVAR), the point where the jacobian ! is evaluated. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) arg real ( kind = 8 ), parameter :: beta = 0.4D+00 real ( kind = 8 ) dg real ( kind = 8 ) factor real ( kind = 8 ), parameter :: gamma = 20.0D+00 real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) s real ( kind = 8 ) t real ( kind = 8 ) trapezoid real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 lambda = x(nvar) m = nvar - 1 h = 1.0D+00 / real ( m - 1, kind = 8 ) do i = 1, m s = h * ( i - 1 ) trapezoid = 0.0D+00 do j = 1, m t = h * ( j - 1 ) arg = beta * gamma * ( 1.0D+00 - x(j) ) & / ( 1.0D+00 + beta * ( 1.0D+00 - x(j) ) ) if ( j == 1 ) then factor = 0.5D+00 else if ( j < m - 1 ) then factor = 1.0D+00 else if ( j == m ) then factor = 0.5D+00 end if trapezoid = trapezoid + h * factor * x(j) * exp ( arg ) * & ( max ( s, t ) - 1.0D+00 ) dg = - beta * gamma / ( 1.0D+00 + beta * ( 1.0D+00 - x(j) ) )**2 jac(i,j) = jac(i,j) - lambda * h * factor * exp ( arg ) * & ( 1.0D+00 + x(j) * dg ) * ( max ( s, t ) - 1.0D+00 ) end do jac(i,i) = jac(i,i) + 1.0D+00 jac(i,nvar) = - trapezoid end do return end subroutine p16_nvar ( option, nvar ) !*****************************************************************************80 ! !! P16_NVAR sets the number of variables for problem 16. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 17 return end subroutine p16_option_num ( option_num ) !*****************************************************************************80 ! !! P16_OPTION_NUM returns the number of options for problem 16. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p16_start ( option, nvar, x ) !*****************************************************************************80 ! !! P16_START returns a starting point for problem 16. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar-1) = 1.0D+00 x(nvar) = 0.0D+00 return end subroutine p16_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P16_STEPSIZE returns step sizes for problem 16. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.200D+00 hmin = 0.001D+00 hmax = 2.000D+00 return end subroutine p16_title ( option, title ) !*****************************************************************************80 ! !! P16_TITLE sets the title for problem 16. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'The Moore Spence Chemical Reaction Integral Equation.' return end subroutine p17_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P17_FUN evaluates the function for problem 17. ! ! Title: ! ! The Bremermann Propane Combustion System ! ! Description: ! ! The equations describe the combustion of propane (C3H4) in air ! (O2 and N2) at 2200 degrees Fahrenheit. The chemical substances ! monitored include: ! ! X(1) CO2 carbon dioxide ! X(2) H2O water ! X(3) N2 ! X(4) CO carbon monoxide ! X(5) H2 ! X(6) H ! X(7) OH ! X(8) O ! X(9) NO ! X(10) O2 ! ! with auxilliary variables ! ! X(11) amount of air: 0.5*X(11) moles of O2, 2*X(11) moles of N2. ! X(12) air pressure in atmospheres. ! ! The mass balance and reaction equations become, once square ! roots are eliminated: ! ! F(1) = X(1) + X(4) - 3.0D+00 ! F(2) = 2 * X(1) + X(2) + X(4) + X(7) + X(8) + X(9) ! + 2 * X(10) - X(12) ! F(3) = 2 * X(2) + 2 * X(5) + X(6) + X(7) - 8.0D+00 ! F(4) = 2 * X(3) + X(9) - 4 * X(12) ! F(5) = X(1) * X(5) - 0.193 * X(2) * X(4) ! F(6) = X(11) * X(1) * X(6)**2 - 0.002597**2 * X(2) * X(4) * XSUM ! F(7) = X(11) * X(4) * X(7)**2 - 0.003448**2 * X(1) * X(2) * XSUM ! F(8) = X(11) * X(4) * X(8) - 0.0001799 * X(1) * XSUM ! F(9) = X(11) * X(4)**2 * X(9)**2 ! - 0.0002155**2 * X(1)**2 * X(3) * XSUM ! F(10)= X(11) * X(4)**2 * X(10) - 0.00003846 * X(1)**2 * XSUM ! ! where ! ! XSUM = Sum ( 1 <= I <= 10 ) X(I) ! ! Options: ! ! OPTION = 1: ! ! FX(11) = X(11) - 1.0D+00 (fixed concentration) ! ! OPTION = 2: ! ! FX(11) = X(12) - 5.0D+00 (fixed pressure) ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Hans Bremermann, ! Calculation of Equilibrium Points for Models of Ecological and ! Chemical Systems, ! in Proceedings of a Conference on the Applications of Undergraduate ! Mathematics in the Engineering, Life, Managerial and Social Sciences, ! Georgia Institute of Technology, June 1973, pages 198-217. ! ! K L Hiebert, ! A Comparison of Software Which Solves Systems of Nonlinear Equations, ! Technical Report SAND-80-0181, 1980, ! Sandia National Laboratory, Albuquerque, New Mexico, ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) U(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at U. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) real ( kind = 8 ) xsum xsum = sum ( x(1:10) ) fx(1) = x(1) + x(4) - 3.0D+00 fx(2) = 2.0D+00 * x(1) + x(2) + x(4) + x(7) + x(8) + x(9) & + 2.0D+00 * x(10) - x(12) fx(3) = 2.0D+00 * x(2) + 2.0D+00 * x(5) + x(6) + x(7) - 8.0D+00 fx(4) = 2.0D+00 * x(3) + x(9) - 4.0D+00 * x(12) fx(5) = x(1) * x(5) - 0.193D+00 * x(2) * x(4) fx(6) = x(11) * x(1) * x(6) * x(6) - 0.002597D+00**2 * x(2) * x(4) * xsum fx(7) = x(11) * x(4) * x(7) * x(7) - 0.003448D+00**2 * x(1) * x(2) * xsum fx(8) = x(11) * x(4) * x(8) - 0.0001799D+00 * x(1) * xsum fx(9) = x(11) * x(4) * x(4) * x(9) * x(9) & - 0.0002155D+00**2 * x(1) * x(1) * x(3) * xsum fx(10) = x(11) * x(4) * x(4) * x(10) - 0.00003846D+00 * x(1) * x(1) * xsum if ( option == 1 ) then fx(11) = x(11) - 1.0D+00 else if ( option == 2 ) then fx(11) = x(12) - 5.0D+00 end if return end subroutine p17_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P17_JAC evaluates the jacobian for problem 17. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) U(NVAR), the point where the jacobian ! is evaluated. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) term real ( kind = 8 ) x(nvar) real ( kind = 8 ) xsum jac(1:nvar,1:nvar) = 0.0D+00 xsum = sum ( x(1:10) ) jac(1,1) = 1.0D+00 jac(1,4) = 1.0D+00 jac(2,1) = 2.0D+00 jac(2,2) = 1.0D+00 jac(2,4) = 1.0D+00 jac(2,7) = 1.0D+00 jac(2,8) = 1.0D+00 jac(2,9) = 1.0D+00 jac(2,10) = 2.0D+00 jac(2,12) = - 1.0D+00 jac(3,2) = 2.0D+00 jac(3,5) = 2.0D+00 jac(3,6) = 1.0D+00 jac(3,7) = 1.0D+00 jac(4,3) = 2.0D+00 jac(4,9) = 1.0D+00 jac(4,12) = - 4.0D+00 jac(5,1) = x(5) jac(5,2) = - 0.193D+00 * x(4) jac(5,4) = - 0.193D+00 * x(2) jac(5,5) = x(1) term = - 0.002597D+00**2 * x(2) * x(4) jac(6,1) = x(6) * x(6) * x(11) + term jac(6,2) = - 0.002597D+00**2 * x(4) * ( xsum + x(2) ) jac(6,3) = term jac(6,4) = - 0.002597D+00**2 * x(2) * ( xsum + x(4) ) jac(6,5) = term jac(6,6) = term + 2.0D+00 * x(1) * x(6) * x(11) jac(6,7) = term jac(6,8) = term jac(6,9) = term jac(6,10) = term jac(6,11) = x(1) * x(6) * x(6) term = - 0.003448D+00**2 * x(1) * x(2) jac(7,1) = - 0.003448D+00**2 * x(2) * ( xsum + x(1) ) jac(7,2) = - 0.003448D+00**2 * x(1) * ( xsum + x(2) ) jac(7,3) = term jac(7,4) = x(7) * x(7) * x(11) + term jac(7,5) = term jac(7,6) = term jac(7,7) = 2.0D+00 * x(4) * x(7) * x(11) + term jac(7,8) = term jac(7,9) = term jac(7,10) = term jac(7,11) = x(4) * x(7) * x(7) term = - 0.0001799D+00 * x(1) jac(8,1) = - 0.0001799D+00 * ( xsum + x(1) ) jac(8,2) = term jac(8,3) = term jac(8,4) = x(8) * x(11) + term jac(8,5) = term jac(8,6) = term jac(8,7) = term jac(8,8) = x(4) * x(11) + term jac(8,9) = term jac(8,10) = term jac(8,11) = x(4) * x(8) term = - 0.0002155D+00**2 * x(1) * x(1) * x(3) jac(9,1) = - 0.0002155D+00**2 * x(1) * x(3) * ( x(1) + 2.0D+00 * xsum ) jac(9,2) = term jac(9,3) = - 0.0002155D+00**2 * x(1) * x(1) * ( x(3) + xsum ) jac(9,4) = 2.0D+00 * x(4) * x(9) * x(9) * x(11) + term jac(9,5) = term jac(9,6) = term jac(9,7) = term jac(9,8) = term jac(9,9) = 2.0D+00 * x(4) * x(4) * x(9) * x(11) + term jac(9,10) = term jac(9,11) = x(4) * x(4) * x(9) * x(9) term = - 0.00003846D+00 * x(1) * x(1) jac(10,1) = - 0.00003846D+00 * x(1) * ( x(1) + 2.0D+00 * xsum ) jac(10,2) = term jac(10,3) = term jac(10,4) = 2.0D+00 * x(4) * x(10) * x(11) + term jac(10,5) = term jac(10,6) = term jac(10,7) = term jac(10,8) = term jac(10,9) = term jac(10,10) = x(4) * x(4) * x(11) + term jac(10,11) = x(4) * x(4) * x(10) if ( option == 1 ) then jac(11,11) = 1.0D+00 else if ( option == 2 ) then jac(11,12) = 1.0D+00 end if return end subroutine p17_nvar ( option, nvar ) !*****************************************************************************80 ! !! P17_NVAR sets the number of variables for problem 17. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 12 return end subroutine p17_option_num ( option_num ) !*****************************************************************************80 ! !! P17_OPTION_NUM returns the number of options for problem 17. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 2 return end subroutine p17_start ( option, nvar, x ) !*****************************************************************************80 ! !! P17_START returns a starting point for problem 17. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1) = 0.3564320D+00 x(2) = 1.636071D+00 x(3) = 9.999810D+00 x(4) = 2.643568D+00 x(5) = 2.341926D+00 x(6) = 0.3732447D-01 x(7) = 0.6681509D-02 x(8) = 0.4128999D-03 x(9) = 0.3790901D-03 x(10) = 0.1190167D-04 if ( option == 1 ) then x(11) = 1.0D+00 x(12) = 5.0D+00 else if ( option == 2 ) then x(11) = 1.0D+00 x(12) = 5.0D+00 end if return end subroutine p17_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P17_STEPSIZE returns step sizes for problem 17. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 1.000D+00 hmin = 0.001D+00 hmax = 2.000D+00 return end subroutine p17_title ( option, title ) !*****************************************************************************80 ! !! P17_TITLE sets the title for problem 17. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'Bremermann Propane Combustion System, fixed pressure.' else if ( option == 2 ) then title = 'Bremermann Propane Combustion System, fixed concentration.' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P17_TITLE - Fatal error!' write ( *, '(a)' ) ' Unrecognized option number.' stop end if return end subroutine p18_fun ( option, nvar, u, fx ) !*****************************************************************************80 ! !! P18_FUN evaluates the function for problem 18. ! ! Title: ! ! The Semiconductor Problem. ! ! Description: ! ! The continuous problem is a two point boundary value problem ! of the form ! ! - U'' = G ( T, U, LAMBDA ) ! ! for A < T < B, with boundary conditions ! ! U(A) = LAMBDA * UA, ! U(B) = LAMBDA * UB. ! ! and with right hand side: ! ! G ( T, U, LAMBDA ) = LAMBDA * ! ( CA * EXP ( LAMBDA * BETA * ( LAMBDA * UA - U ) ) ! - CB * EXP ( LAMBDA * BETA * ( U - LAMBDA * UB ) ) + H(T) ) ! ! and ! ! H(T) = - CA for T <= 0, ! = CB for 0 < T. ! ! The discrete version of the problem uses a mesh of M points ! T(1) = A, T(2) = A + H, T(3) = A * 2 * H, ..., T(M) + B, ! and corresponding solution values U(I). The system of ! M equations is: ! ! U(1) = LAMBDA * UA ! ! - U(I-1) + 2 * U(I) - U(I+1) = 2 * H * LAMBDA * G ( T(I), U(I), LAMBDA ) ! ! U(M) = LAMBDA * UB ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! SJ Polak, A Wachten, H Vaes, A deBeer, Cor denHeijer, ! A Continuation Method for the Calculation of Electrostatic ! Potentials in Semiconductors,
! Technical Report ISA-TIS/CARD,
! NV Philips Gloeilampen-Fabrieken, 1979. ! ! Cor denHeijer, Werner Rheinboldt, ! On Steplength Algorithms for a Class of Continuation Methods, ! SIAM Journal on Numerical Analysis, ! Volume 18, Number 5, October 1981, pages 925-947. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) U(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at U. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ), parameter :: a = 0.0D+00 real ( kind = 8 ), parameter :: b = 0.010D+00 real ( kind = 8 ) del2x real ( kind = 8 ) fx(nvar-1) real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) p18_gx real ( kind = 8 ) t real ( kind = 8 ) u(nvar) real ( kind = 8 ), parameter :: ua = 0.0D+00 real ( kind = 8 ), parameter :: ub = 25.0D+00 lambda = u(nvar) m = nvar - 1 h = 1.0D+00 / real ( m - 1, kind = 8 ) fx(1) = u(1) - lambda * ua do i = 2, m - 1 t = ( real ( m - i, kind = 8 ) * a & + real ( i - 1, kind = 8 ) * b ) & / real ( m - 1, kind = 8 ) del2x = ( u(i-1) - 2.0D+00 * u(i) + u(i+1) ) / ( 2.0D+00 * h ) fx(i) = del2x - p18_gx ( t, u(i), lambda ) end do fx(m) = u(m) - lambda * ub return end function p18_gpl ( t, u, lambda ) !*****************************************************************************80 ! !! P18_GPL evaluates d G ( T, U, LAMBDA ) / d LAMBDA. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 23 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) T, U, LAMBDA, the arguments of the function. ! ! Output, real ( kind = 8 ) P18_GPL, the derivative of the function with ! respect to LAMBDA. ! implicit none real ( kind = 8 ), parameter :: beta = 20.0D+00 real ( kind = 8 ), parameter :: ca = 1.0D+06 real ( kind = 8 ), parameter :: cb = 1.0D+07 real ( kind = 8 ) e1 real ( kind = 8 ) e2 real ( kind = 8 ) ht real ( kind = 8 ) lambda real ( kind = 8 ) p18_gpl real ( kind = 8 ) t real ( kind = 8 ) u real ( kind = 8 ), parameter :: ua = 0.0D+00 real ( kind = 8 ), parameter :: ub = 25.0D+00 if ( t <= 0.0D+00 ) then ht = - ca else ht = cb end if e1 = exp ( lambda * beta * ( lambda * ua - u ) ) e2 = exp ( lambda * beta * ( u - lambda * ub ) ) p18_gpl = ht + ca * e1 - cb * e2 + lambda * & ( ca * beta * ( 2.0D+00 * lambda * ua - u ) * e1 & - cb * beta * ( u - 2.0D+00 * lambda * ub ) * e2 ) return end function p18_gpu ( u, lambda ) !*****************************************************************************80 ! !! P18_GPU evaluates d G ( T, U, LAMBDA ) / dU. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) U, LAMBDA, the arguments of the function. ! ! Output, real ( kind = 8 ) P18_GPU, the derivative of the function with ! respect to U. ! implicit none real ( kind = 8 ), parameter :: beta = 20.0D+00 real ( kind = 8 ), parameter :: ca = 1.0D+06 real ( kind = 8 ), parameter :: cb = 1.0D+07 real ( kind = 8 ) lambda real ( kind = 8 ) p18_gpu real ( kind = 8 ) u real ( kind = 8 ), parameter :: ua = 0.0D+00 real ( kind = 8 ), parameter :: ub = 25.0D+00 p18_gpu = - lambda * lambda * beta * ( & ca * exp ( lambda * beta * ( lambda * ua - u ) ) & + cb * exp ( lambda * beta * ( u - lambda * ub ) ) ) return end function p18_gx ( t, u, lambda ) !*****************************************************************************80 ! !! P18_GX evaluates the auxilliary function G ( T, U, LAMBDA ). ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) T, U, LAMBDA, the arguments of the function. ! ! Output, real ( kind = 8 ) P18_GX, the value of the function. ! implicit none real ( kind = 8 ), parameter :: beta = 20.0D+00 real ( kind = 8 ), parameter :: ca = 1.0D+06 real ( kind = 8 ), parameter :: cb = 1.0D+07 real ( kind = 8 ) ht real ( kind = 8 ) lambda real ( kind = 8 ) p18_gx real ( kind = 8 ) t real ( kind = 8 ) u real ( kind = 8 ), parameter :: ua = 0.0D+00 real ( kind = 8 ), parameter :: ub = 25.0D+00 if ( t <= 0.0D+00 ) then ht = - ca else ht = cb end if p18_gx = lambda * ( ht + ca * exp ( lambda * beta * ( lambda * ua - u ) ) & - cb * exp ( lambda * beta * ( u - lambda * ub ) ) ) return end subroutine p18_jac ( option, nvar, u, jac ) !*****************************************************************************80 ! !! P18_JAC evaluates the jacobian for problem 18. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) U(NVAR), the point where the jacobian ! is evaluated. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ), parameter :: a = 0.0D+00 real ( kind = 8 ), parameter :: b = 0.01D+00 real ( kind = 8 ) h integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ) p18_gpl real ( kind = 8 ) p18_gpu real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) lambda integer ( kind = 4 ) m real ( kind = 8 ) t real ( kind = 8 ) u(nvar) real ( kind = 8 ), parameter :: ua = 0.0D+00 real ( kind = 8 ), parameter :: ub = 25.0D+00 jac(1:nvar,1:nvar) = 0.0D+00 lambda = u(nvar) m = nvar - 1 h = 1.0D+00 / real ( m - 1, kind = 8 ) jac(1,1) = 1.0D+00 jac(1,nvar) = - ua do i = 2, m - 1 t = ( real ( m - i, kind = 8 ) * a & + real ( i - 1, kind = 8 ) * b ) & / real ( m - 1, kind = 8 ) jac(i,i-1) = 0.5D+00 / h jac(i,i) = - 1.0D+00 / h - p18_gpu ( u(i), lambda ) jac(i,i+1) = 0.5D+00 / h jac(i,nvar) = - p18_gpl ( t, u(i), lambda ) end do jac(m,m) = 1.0D+00 jac(m,nvar) = - ub return end subroutine p18_nvar ( option, nvar ) !*****************************************************************************80 ! !! P18_NVAR sets the number of variables for problem 18. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 12 return end subroutine p18_option_num ( option_num ) !*****************************************************************************80 ! !! P18_OPTION_NUM returns the number of options for problem 18. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p18_start ( option, nvar, x ) !*****************************************************************************80 ! !! P18_START returns a starting point for problem 18. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:nvar) = 0.0D+00 return end subroutine p18_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P18_STEPSIZE returns step sizes for problem 18. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 2.500D+00 hmin = 0.001D+00 hmax = 5.000D+00 return end subroutine p18_title ( option, title ) !*****************************************************************************80 ! !! P18_TITLE sets the title for problem 18. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'The Semiconductor Problem.' return end subroutine p19_con ( nvar, press, temper, x, con, flow ) !*****************************************************************************80 ! !! P19_CON returns physical constants. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) PRESS, the pressure in atmospheres. ! ! Input, real ( kind = 8 ) TEMPER, the temperature in degrees Kelvin. ! ! Input, real ( kind = 8 ) X(NVAR), the point where the jacobian ! is evaluated. ! ! Output, real ( kind = 8 ) CON(5), the equilibrium constants for ! the reagants. ! ! Output, real ( kind = 8 ) FLOW(5), the flow rates for the reagants. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) arg real ( kind = 8 ) con(5) real ( kind = 8 ) flow(5) real ( kind = 8 ) press real ( kind = 8 ) temper real ( kind = 8 ) x(nvar) ! ! Set flow rates. ! flow(1) = 10.0D+00 flow(2) = 10.0D+00 flow(3) = 10.0D+00 flow(4) = 100.0D+00 flow(5) = 100.0D+00 ! ! Set the equilibrium constants. ! con(1) = 1333.0D+00 / press con(2) = 33.0D+00 / press con(3) = 28780.0D+00 / press arg = 11.99D+00 - 4004.0D+00 / ( temper - 39.06 ) & - 8546.0D+00 * x(5) * x(5) / temper & + 4.0D+00 * x(5) * x(5) + 6754.0D+00 * x(5) * x(5) * x(4) / temper & - 8.0D+00 * x(5) * x(5) * x(4) - log ( press ) con(4) = exp ( arg ) arg = 10.98D+00 - 3362.0D+00 / ( temper - 50.79D+00 ) & - 2872.0D+00 * x(4) * x(4) / temper & - 6754.0D+00 * x(5) * x(4) * x(4) / temper & + 8.0D+00 * x(5) * x(4) * x(4) - log ( press ) con(5) = exp ( arg ) return end subroutine p19_conp ( con, nvar, temper, x, dc4dx4, dc4dx5, dc5dx4, dc5dx5 ) !*****************************************************************************80 ! !! P19_CONP returns physical constant derivatives. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) CON(5), the equilibrium constants for ! the reagants. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) TEMPER, the temperature in degrees Kelvin. ! ! Input, real ( kind = 8 ) X(NVAR), the point where the jacobian ! is evaluated. ! ! Output, real ( kind = 8 ) DC4DX4, DC4DX5, DC5DX4, DC5DX5, the values of ! d CON(4)/d X(4), d CON(4)/d X(5), d CON(5)/d X(4) and d CON(5)/d X(5). ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) con(5) real ( kind = 8 ) dc4dx4 real ( kind = 8 ) dc4dx5 real ( kind = 8 ) dc5dx4 real ( kind = 8 ) dc5dx5 real ( kind = 8 ) temper real ( kind = 8 ) x(nvar) dc4dx4 = con(4) * ( 6754.0D+00 * x(5) * x(5) & / temper - 8.0D+00 * x(5) * x(5) ) dc4dx5 = con(4) * ( -8546.0D+00 * 2.0D+00 * x(5) / temper & + 8.0D+00 * x(5) + 6754.0D+00 * 2.0D+00 * x(4) * x(5) / temper & - 16.0D+00 * x(5) * x(4) ) dc5dx4 = con(5) * ( -2872.0D+00 * 2.0D+00 * x(4) / temper & - 6754.0D+00 * 2.0D+00 * x(4) * x(5) / temper + 16.0D+00 * x(4) * x(5) ) dc5dx5 = con(5) * ( -6754.0D+00 * x(4) * x(4) / temper & + 8.0D+00 * x(4) * x(4) ) return end subroutine p19_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P19_FUN evaluates the function for problem 19. ! ! Title: ! ! Nitric acid absorption problem ! ! Description: ! ! Physical Constants: ! ! CON - physical equilibrium constants for the five reagents. ! FLOW - flow rates for the five reagants in moles/hour. ! PRESS - pressure in atmospheres ! TEMPER - temperature in Kelvin ! ! Variables: ! ! Entries 1 to 5 are the relative concentrations of liquid: ! ! X(1) = liquid NO2. ! X(2) = liquid N2O4. ! X(3) = liquid NO. ! X(4) = liquid H2O. ! X(5) = liquid HNO3. ! ! Entries 6 through 10 are the relative concentrations of vapor: ! ! X(6) = vapor NO2. ! X(7) = vapor N2O4. ! X(8) = vapor NO. ! X(9) = vapor H2O. ! X(10) = vapor HNO3. ! ! Entries 11 and 12 are the number of moles: ! ! X(11) = moles of liquid. ! X(12) = moles of vapor. ! ! Entry 13 is LAMBDA: ! ! X(13) = LAMBDA, flowrate multiplier. ! ! Equations: ! ! Mole Balance equations, I = 1 to 5: ! ! FX(I) = X(11) * X(I) + X(12) * X(I+5) - X(13) * FLOW(I) ! ! Liquid-Vapor Transfer equations, I = 6 to 10: ! ! FX(I) = X(I) - CON(I-5) * X(I-5) ! ! Liquid and Vapor proportions add to 1: ! ! FX(11) = X(1) + X(2) + X(3) + X(4) + X(5) - 1.0D+00 ! FX(12) = X(6) + X(7) + X(8) + X(9) + X(10) - 1.0D+00 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Tama Copeman, ! Air Products and Chemicals, Inc. ! Box 538, ! Allentown, Pennsylvania, 18105. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) con(5) real ( kind = 8 ) flow(5) real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ), parameter :: press = 7.0D+00 real ( kind = 8 ), parameter :: temper = 323.0D+00 real ( kind = 8 ) x(nvar) ! ! Get chemical constants. ! call p19_con ( nvar, press, temper, x, con, flow ) ! ! Evaluate the Mole Balance equations: ! do i = 1, 5 fx(i) = x(11) * x(i) + x(12) * x(i+5) - x(13) * flow(i) end do ! ! Evaluate the Liquid-Vapor Transfer equations: ! do i = 6, 10 fx(i) = x(i) - con(i-5) * x(i-5) end do ! ! Evaluate the Liquid and Vapor Proportion equations: ! fx(11) = x(1) + x(2) + x(3) + x(4) + x(5) - 1.0D+00 fx(12) = x(6) + x(7) + x(8) + x(9) + x(10) - 1.0D+00 return end subroutine p19_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P19_JAC evaluates the jacobian for problem 19. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the point where the jacobian ! is evaluated. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) con(5) real ( kind = 8 ) dc4dx4 real ( kind = 8 ) dc4dx5 real ( kind = 8 ) dc5dx4 real ( kind = 8 ) dc5dx5 real ( kind = 8 ) flow(5) real ( kind = 8 ) jac(nvar,nvar) integer ( kind = 4 ) i integer ( kind = 4 ) option integer ( kind = 4 ) j real ( kind = 8 ), parameter :: press = 7.0D+00 real ( kind = 8 ), parameter :: temper = 323.0D+00 real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 ! ! Get chemical constants. ! call p19_con ( nvar, press, temper, x, con, flow ) ! ! Get derivatives of chemical constants. ! call p19_conp ( con, nvar, temper, x, dc4dx4, dc4dx5, dc5dx4, dc5dx5 ) ! ! Differentiate the Mole Balance equations: ! do i = 1, 5 jac(i,i) = x(11) jac(i,i+5) = x(12) jac(i,11) = x(i) jac(i,12) = x(i+5) jac(i,13) = - flow(i) end do ! ! Differentiate the Liquid-Vapor Transfer equations: ! do i = 6, 10 jac(i,i) = 1.0D+00 jac(i,i-5) = - con(i-5) end do jac(9,4) = jac(9,4) - dc4dx4 * x(4) jac(9,5) = jac(9,5) - dc4dx5 * x(5) jac(10,4) = jac(10,4) - dc5dx4 * x(4) jac(10,5) = jac(10,5) - dc5dx5 * x(5) ! ! Differentiate the Liquid and Vapor Proportion equations: ! jac(11,1:5) = 1.0D+00 jac(12,6:10) = 1.0D+00 return end subroutine p19_nvar ( option, nvar ) !*****************************************************************************80 ! !! P19_NVAR sets the number of variables for problem 19. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 13 return end subroutine p19_option_num ( option_num ) !*****************************************************************************80 ! !! P19_OPTION_NUM returns the number of options for problem 19. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p19_start ( option, nvar, x ) !*****************************************************************************80 ! !! P19_START returns a starting point for problem 19. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) i integer ( kind = 4 ) option real ( kind = 8 ) x(nvar) x(1:13) = (/ & 0.00218216D+00, & 0.03171126D+00, & 0.00010562D+00, & 0.48301846D+00, & 0.48298250D+00, & 0.41554567D+00, & 0.14949595D+00, & 0.43425476D+00, & 0.00018983D+00, & 0.00051379D+00, & 207.02239583D+00, & 22.97760417D+00, & 1.00000000D+00 /) return end subroutine p19_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P19_STEPSIZE returns step sizes for problem 19. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 24 September 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.125000D+00 hmin = 0.015625D+00 hmax = 4.000000D+00 return end subroutine p19_title ( option, title ) !*****************************************************************************80 ! !! P19_TITLE sets the title for problem 19. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 03 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title title = 'Nitric Acid Absorption Flash.' return end subroutine p20_fun ( option, nvar, x, fx ) !*****************************************************************************80 ! !! P20_FUN evaluates the function for problem 20. ! ! Title: ! ! The Buckling Spring ! ! Description: ! ! We are given three points A, B, and C. ! A is at the origin (0,0). ! B has coordinates (X,Y) with Y nonnegative, and the ray from A to B ! makes an angle of THETA with the horizontal axis. ! C is at the point (2*X,0). ! ! A spring extends from A to B, and is normally of length 1, ! and is currently of length L. ! A spring extends from B to C, and is normally of length 1, ! and is currently of length L. ! A spring force is also exerted, which tends to draw the two ! springs together, proportional to the angle between the two springs. ! ! A vertical load MU is applied at point B (downward is positive). ! A horizontal load LAMBDA is applied at point C (leftware is positive). ! The spring force is applied perpendicularly to the axes of the two springs. ! ! If we compute F(1), the force along the axis of one spring, and ! F(2), the force perpendicular to the axis of one spring, we have that ! F(L,THETA,LAMBDA,MU) is given by: ! ! F(1) = - 2 ( 1 - L ) + 2 * LAMBDA * cos ( THETA ) + MU * sin ( THETA ) ! F(2) = 0.5 * THETA - 2 * LAMBDA * L * sin ( THETA ) ! + MU * L * cos ( THETA ) ! ! The user must specify a third, augmenting equation, of the form ! ! F(3) = X(HOLD_INDEX) - HOLD_VALUE. ! ! Typically, HOLD_INDEX is 2, for the varlable THETA, and HOLD_VALUE is ! an angle measured in radians and strictly between 0 and PI/2. ! ! Another choice for HOLD_INDEX would be 1, for the variable L, with ! HOLD_VALUE greater than 0. Values of L less than 1 represent compressed ! springs; values greater than 1 indicate extended springs. ! ! L represents the current length of the springs. ! THETA represents the angle that the springs make with the horizontal axis. ! MU is a vertical load applied at the midpoint B. ! LAMBDA is a horizontal load applied at the right endpoint C. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Tim Poston, Ian Stewart, ! Catastrophe Theory and its Applications, ! Dover, 1996, ! ISBN13: 978-0486692715, ! LC: QA614.58.P66. ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the function. ! ! Output, real ( kind = 8 ) FX(NVAR-1), the value of the function at X. ! implicit none integer ( kind = 4 ) nvar real ( kind = 8 ) fx(nvar-1) integer ( kind = 4 ) hold_index real ( kind = 8 ) hold_value real ( kind = 8 ) l real ( kind = 8 ) lambda real ( kind = 8 ) mu integer ( kind = 4 ) option real ( kind = 8 ) theta real ( kind = 8 ) x(nvar) l = x(1) theta = x(2) lambda = x(3) mu = x(4) fx(1) = - 2.0D+00 * ( 1.0D+00 - l ) & + 2.0D+00 * lambda * cos ( theta ) & + mu * sin ( theta ) fx(2) = 0.5D+00 * theta & - 2.0D+00 * lambda * l * sin ( theta ) & + mu * l * cos ( theta ) call p20_i4_get ( 'hold_index', hold_index ) call p20_r8_get ( 'hold_value', hold_value ) fx(3) = x(hold_index) - hold_value return end subroutine p20_i4_get ( name, value ) !*****************************************************************************80 ! !! P20_I4_GET returns the value of an integer parameter for problem 20. ! ! Discussion: ! ! The only legal input name is 'hold_index', which indicates the ! index of the variable to be held fixed. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) NAME, the name of the variable. ! ! Output, integer ( kind = 4 ) VALUE, the value of the variable. ! implicit none character ( len = * ) name integer ( kind = 4 ) value call p20_i4_store ( 'get', name, value ) return end subroutine p20_i4_set ( name, value ) !*****************************************************************************80 ! !! P20_I4_SET sets the value of an integer parameter for problem 20. ! ! Discussion: ! ! The only legal input name is 'hold_index', which indicates the ! index of the variable to be held fixed. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) NAME, the name of the variable. ! ! Input, integer ( kind = 4 ) VALUE, the value of the variable. ! implicit none character ( len = * ) name integer ( kind = 4 ) value call p20_i4_store ( 'set', name, value ) return end subroutine p20_i4_store ( action, name, value ) !*****************************************************************************80 ! !! P20_I4_STORE sets or gets the value of an integer parameter for problem 20. ! ! Discussion: ! ! The only legal input name is 'hold_index', which indicates the ! index of the variable to be held fixed. This variable is given ! the default value of 2. ! ! The only legal values of 'hold_index' are 1 and 2. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) ACTION, either 'get' or 'set'. ! ! Input, character ( len = * ) NAME, the name of the variable. ! ! Input/output, integer ( kind = 4 ) VALUE, the value of the variable. ! implicit none character ( len = * ) action integer ( kind = 4 ), save :: hold_index = 2 character ( len = * ) name logical s_eqi integer ( kind = 4 ) value if ( s_eqi ( action, 'get' ) ) then if ( s_eqi ( name, 'hold_index' ) ) then value = hold_index else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_I4_STORE - Fatal error!' write ( *, '(a)' ) ' Unexpected "get" of NAME = "' // name // '".' stop end if else if ( s_eqi ( action, 'set' ) ) then if ( s_eqi ( name, 'hold_index' ) ) then if ( value == 1 .or. value == 2 ) then hold_index = value else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_I4_STORE - Fatal error!' write ( *, '(a,i8)' ) ' Unacceptable value for HOLD_INDEX = ', value write ( *, '(a)' ) ' Acceptable values are 1 and 2.' stop end if else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_I4_STORE - Fatal error!' write ( *, '(a)' ) ' Unexpected "set" of NAME = "' // name // '".' stop end if else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_I4_STORE - Fatal error!' write ( *, '(a)' ) ' Unexpected ACTION = "' // action // '".' stop end if return end subroutine p20_jac ( option, nvar, x, jac ) !*****************************************************************************80 ! !! P20_JAC evaluates the jacobian for problem 20. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Input, real ( kind = 8 ) X(NVAR), the argument of the jacobian. ! ! Output, real ( kind = 8 ) JAC(NVAR,NVAR), the jacobian matrix evaluated ! at X. The NVAR-th row is not set by this routine. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) hold_index real ( kind = 8 ) jac(nvar,nvar) real ( kind = 8 ) l real ( kind = 8 ) lambda real ( kind = 8 ) mu integer ( kind = 4 ) option real ( kind = 8 ) theta real ( kind = 8 ) x(nvar) jac(1:nvar,1:nvar) = 0.0D+00 l = x(1) theta = x(2) lambda = x(3) mu = x(4) jac(1,1) = 2.0D+00 jac(1,2) = - 2.0D+00 * lambda * sin ( theta ) + mu * cos ( theta ) jac(1,3) = 2.0D+00 * cos ( theta ) jac(1,4) = sin ( theta ) jac(2,1) = - 2.0D+00 * lambda * sin ( theta ) + mu * cos ( theta ) jac(2,2) = 0.5D+00 - 2.0D+00 * lambda * l * cos ( theta ) & - mu * l * sin ( theta ) jac(2,3) = - 2.0D+00 * l * sin ( theta ) jac(2,4) = l * cos ( theta ) call p20_i4_get ( 'hold_index', hold_index ) jac(3,hold_index) = 1.0D+00 return end subroutine p20_nvar ( option, nvar ) !*****************************************************************************80 ! !! P20_NVAR sets the number of variables for problem 20. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option chosen for this problem. ! For some problems, several options are available. At least, ! OPTION = 1 is always legal. ! ! Output, integer ( kind = 4 ) NVAR, the number of variables. ! implicit none integer ( kind = 4 ) option integer ( kind = 4 ) nvar nvar = 4 return end subroutine p20_option_num ( option_num ) !*****************************************************************************80 ! !! P20_OPTION_NUM returns the number of options for problem 20. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) OPTION_NUM, the number of options. ! implicit none integer ( kind = 4 ) option_num option_num = 1 return end subroutine p20_r8_get ( name, value ) !*****************************************************************************80 ! !! P20_R8_GET returns the value of a real parameter for problem 20. ! ! Discussion: ! ! The only legal input name is 'hold_value', which indicates the ! value of the variable to be held fixed. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) NAME, the name of the variable. ! ! Output, real ( kind = 8 ) VALUE, the value of the variable. ! implicit none character ( len = * ) name real ( kind = 8 ) value call p20_r8_store ( 'get', name, value ) return end subroutine p20_r8_set ( name, value ) !*****************************************************************************80 ! !! P20_R8_SET sets the value of a real parameter for problem 20. ! ! Discussion: ! ! The only legal input name is 'hold_value', which indicates the ! value of the variable to be held fixed. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) NAME, the name of the variable. ! ! Input, real ( kind = 8 ) VALUE, the value of the variable. ! implicit none character ( len = * ) name real ( kind = 8 ) value call p20_r8_store ( 'set', name, value ) return end subroutine p20_r8_store ( action, name, value ) !*****************************************************************************80 ! !! P20_R8_STORE sets or gets the value of a real parameter for problem 20. ! ! Discussion: ! ! The only legal input name is 'hold_value', which indicates the ! value of the variable to be held fixed. This variable is given ! the default value of pi/8. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) ACTION, either 'get' or 'set'. ! ! Input, character ( len = * ) NAME, the name of the variable. ! ! Input/output, real ( kind = 8 ) VALUE, the value of the variable. ! implicit none character ( len = * ) action real ( kind = 8 ), save :: hold_value = 0.39269908169872415481 character ( len = * ) name logical s_eqi real ( kind = 8 ) value if ( s_eqi ( action, 'get' ) ) then if ( s_eqi ( name, 'hold_value' ) ) then value = hold_value else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_R8_STORE - Fatal error!' write ( *, '(a)' ) ' Unexpected "get" of NAME = "' // name // '".' stop end if else if ( s_eqi ( action, 'set' ) ) then if ( s_eqi ( name, 'hold_value' ) ) then hold_value = value else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_R8_STORE - Fatal error!' write ( *, '(a)' ) ' Unexpected "set" of NAME = "' // name // '".' stop end if else write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_R8_STORE - Fatal error!' write ( *, '(a)' ) ' Unexpected ACTION = "' // action // '".' stop end if return end subroutine p20_setup ( l, theta, lambda, mu ) !*****************************************************************************80 ! !! P20_SETUP finds a solution (L,THETA,LAMBDA,MU) given L and THETA. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) L, THETA, the values of L and THETA. ! ! Output, real ( kind = 8 ) LAMBDA, MU, values for LAMBDA and MU. ! implicit none real ( kind = 8 ) l real ( kind = 8 ) lambda real ( kind = 8 ) mu real ( kind = 8 ) theta mu = 2.0D+00 * ( 1.0D+00 - l ) * sin ( theta ) & - 0.5D+00 * cos ( theta ) * theta / l lambda = ( ( 1.0D+00 - l ) - 0.5D+00 * mu * sin ( theta ) ) / cos ( theta ) return end subroutine p20_start ( option, nvar, x ) !*****************************************************************************80 ! !! P20_START returns a starting point for problem 20. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Input, integer ( kind = 4 ) NVAR, the number of variables. ! ! Output, real ( kind = 8 ) X(NVAR), the starting point. ! implicit none integer ( kind = 4 ) nvar integer ( kind = 4 ) hold_index real ( kind = 8 ) hold_value real ( kind = 8 ) l real ( kind = 8 ) lambda real ( kind = 8 ) mu integer ( kind = 4 ) option real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 real ( kind = 8 ) theta real ( kind = 8 ) x(nvar) call p20_i4_get ( 'hold_index', hold_index ) call p20_r8_get ( 'hold_value', hold_value ) if ( hold_index == 1 ) then l = hold_value theta = pi / 8.0D+00 else if ( hold_index == 2 ) then l = 0.25D+00 theta = hold_value else l = 0.25D+00 theta = pi / 8.0D+00 end if call p20_setup ( l, theta, lambda, mu ) x(1:nvar) = (/ l, theta, lambda, mu /) return end subroutine p20_stepsize ( option, h, hmin, hmax ) !*****************************************************************************80 ! !! P20_STEPSIZE returns step sizes for problem 20. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, real ( kind = 8 ) H, HMIN, HMAX, suggested values for the ! initial step, the minimum step, and the maximum step. ! implicit none real ( kind = 8 ) h real ( kind = 8 ) hmax real ( kind = 8 ) hmin integer ( kind = 4 ) option h = 0.0025000D+00 hmin = 0.01000D+00 hmax = 0.08000D+00 return end subroutine p20_title ( option, title ) !*****************************************************************************80 ! !! P20_TITLE sets the title for problem 20. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 13 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OPTION, the option index. ! ! Output, character ( len = * ) TITLE, the title of the problem. ! TITLE will never be longer than 80 characters. ! implicit none integer ( kind = 4 ) option character ( len = * ) title if ( option == 1 ) then title = 'The Buckling Spring, F(L,Theta,Lambda,Mu).' else title = '???' write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'P20_TITLE - Fatal error!' write ( *, '(a)' ) ' Unrecognized option number.' stop end if return end function r8_mop ( i ) !*****************************************************************************80 ! !! R8_MOP returns the I-th power of -1 as an R8 value. ! ! Discussion: ! ! An R8 is a real ( kind = 8 ) value. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 07 November 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) I, the power of -1. ! ! Output, real ( kind = 8 ) R8_MOP, the I-th power of -1. ! implicit none integer ( kind = 4 ) i real ( kind = 8 ) r8_mop if ( mod ( i, 2 ) == 0 ) then r8_mop = + 1.0D+00 else r8_mop = - 1.0D+00 end if return end function r8_sign ( x ) !*****************************************************************************80 ! !! R8_SIGN returns the sign of an R8. ! ! Discussion: ! ! value = -1 if X < 0; ! value = 0 if X => 0. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 27 March 2004 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) X, the number whose sign is desired. ! ! Output, real ( kind = 8 ) R8_SIGN, the sign of X: ! implicit none real ( kind = 8 ) r8_sign real ( kind = 8 ) x if ( x < 0.0D+00 ) then r8_sign = -1.0D+00 else r8_sign = +1.0D+00 end if return end subroutine r8_swap ( x, y ) !*****************************************************************************80 ! !! R8_SWAP swaps two R8's. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 01 May 2000 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input/output, real ( kind = 8 ) X, Y. On output, the values of X and ! Y have been interchanged. ! implicit none real ( kind = 8 ) x real ( kind = 8 ) y real ( kind = 8 ) z z = x x = y y = z return end function r8_uniform_01 ( seed ) !*****************************************************************************80 ! !! R8_UNIFORM_01 returns a unit pseudorandom R8. ! ! Discussion: ! ! An R8 is a real ( kind = 8 ) value. ! ! For now, the input quantity SEED is an integer variable. ! ! This routine implements the recursion ! ! seed = ( 16807 * seed ) mod ( 2^31 - 1 ) ! r8_uniform_01 = seed / ( 2^31 - 1 ) ! ! The integer arithmetic never requires more than 32 bits, ! including a sign bit. ! ! If the initial seed is 12345, then the first three computations are ! ! Input Output R8_UNIFORM_01 ! SEED SEED ! ! 12345 207482415 0.096616 ! 207482415 1790989824 0.833995 ! 1790989824 2035175616 0.947702 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R8_UNIFORM_01, a new pseudorandom variate, ! strictly between 0 and 1. ! implicit none integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 8 ) r8_uniform_01 integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if ! ! Although SEED can be represented exactly as a 32 bit integer, ! it generally cannot be represented exactly as a 32 bit real number! ! r8_uniform_01 = real ( seed, kind = 8 ) * 4.656612875D-10 return end subroutine r8mat_det ( n, a, det ) !*****************************************************************************80 ! !! R8MAT_DET computes the determinant of an R8MAT. ! ! Discussion: ! ! An R8MAT is an array of R8 values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 07 December 2004 ! ! Author: ! ! Original FORTRAN77 version by Helmut Spaeth ! FORTRAN90 version by John Burkardt ! ! Reference: ! ! Helmut Spaeth, ! Cluster Analysis Algorithms ! for Data Reduction and Classification of Objects, ! Ellis Horwood, 1980, page 125-127. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the order of the matrix. ! ! Input, real ( kind = 8 ) A(N,N), the matrix whose determinant is desired. ! ! Output, real ( kind = 8 ) DET, the determinant of the matrix. ! implicit none integer ( kind = 4 ) n real ( kind = 8 ) a(n,n) real ( kind = 8 ) b(n,n) real ( kind = 8 ) det integer ( kind = 4 ) j integer ( kind = 4 ) k integer ( kind = 4 ) m integer ( kind = 4 ) piv(1) real ( kind = 8 ) t b(1:n,1:n) = a(1:n,1:n) det = 1.0D+00 do k = 1, n piv = maxloc ( abs ( b(k:n,k) ) ) m = piv(1) + k - 1 if ( m /= k ) then det = - det t = b(m,k) b(m,k) = b(k,k) b(k,k) = t end if det = det * b(k,k) if ( b(k,k) /= 0.0D+00 ) then b(k+1:n,k) = -b(k+1:n,k) / b(k,k) do j = k + 1, n if ( m /= k ) then t = b(m,j) b(m,j) = b(k,j) b(k,j) = t end if b(k+1:n,j) = b(k+1:n,j) + b(k+1:n,k) * b(k,j) end do end if end do return end subroutine r8mat_nullspace ( m, n, a, nullspace_size, nullspace ) !*****************************************************************************80 ! !! R8MAT_NULLSPACE computes the nullspace of a matrix. ! ! Discussion: ! ! Let A be an MxN matrix. ! ! If X is an N-vector, and A*X = 0, then X is a null vector of A. ! ! The set of all null vectors of A is called the nullspace of A. ! ! The 0 vector is always in the null space. ! ! If the 0 vector is the only vector in the nullspace of A, then A ! is said to have maximum column rank. (Because A*X=0 can be regarded ! as a linear combination of the columns of A). In particular, if A ! is square, and has maximum column rank, it is nonsingular. ! ! The dimension of the nullspace is the number of linearly independent ! vectors that span the nullspace. If A has maximum column rank, ! its nullspace has dimension 0. ! ! This routine uses the reduced row echelon form of A to determine ! a set of NULLSPACE_SIZE independent null vectors. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 02 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns of ! the matrix A. ! ! Input, real ( kind = 8 ) A(M,N), the matrix to be analyzed. ! ! Input, integer ( kind = 4 ) NULLSPACE_SIZE, the size of the nullspace. ! ! Output, real ( kind = 8 ) NULLSPACE(N,NULLSPACE_SIZE), vectors that ! span the nullspace. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n integer ( kind = 4 ) nullspace_size real ( kind = 8 ) a(m,n) integer ( kind = 4 ) col(n) integer ( kind = 4 ) i integer ( kind = 4 ) i2 integer ( kind = 4 ) j integer ( kind = 4 ) j2 real ( kind = 8 ) nullspace(n,nullspace_size) integer ( kind = 4 ) row(m) real ( kind = 8 ) rref(m,n) ! ! Make a copy of A. ! rref(1:m,1:n) = a(1:m,1:n) ! ! Get the reduced row echelon form of A. ! call r8mat_rref ( m, n, rref ) ! ! Note in ROW the columns of the leading nonzeros. ! COL(J) = +J if there is a leading 1 in that column, and -J otherwise. ! row(1:m) = 0 do j = 1, n col(j) = - j end do do i = 1, m do j = 1, n if ( rref(i,j) == 1.0D+00 ) then row(i) = j col(j) = j exit end if end do end do nullspace(1:n,1:nullspace_size) = 0.0D+00 j2 = 0 ! ! If column J does not contain a leading 1, then it contains ! information about a null vector. ! do j = 1, n if ( col(j) < 0 ) then j2 = j2 + 1 do i = 1, m if ( rref(i,j) /= 0.0D+00 ) then i2 = row(i) nullspace(i2,j2) = - rref(i,j) end if end do nullspace(j,j2) = 1.0D+00 end if end do return end subroutine r8mat_nullspace_size ( m, n, a, nullspace_size ) !*****************************************************************************80 ! !! R8MAT_NULLSPACE_SIZE computes the size of the nullspace of a matrix. ! ! Discussion: ! ! Let A be an MxN matrix. ! ! If X is an N-vector, and A*X = 0, then X is a null vector of A. ! ! The set of all null vectors of A is called the nullspace of A. ! ! The 0 vector is always in the null space. ! ! If the 0 vector is the only vector in the nullspace of A, then A ! is said to have maximum column rank. (Because A*X=0 can be regarded ! as a linear combination of the columns of A). In particular, if A ! is square, and has maximum column rank, it is nonsingular. ! ! The dimension of the nullspace is the number of linearly independent ! vectors that span the nullspace. If A has maximum column rank, ! its nullspace has dimension 0. ! ! This routine ESTIMATES the dimension of the nullspace. Cases of ! singularity that depend on exact arithmetic will probably be missed. ! ! The nullspace will be estimated by counting the leading 1's in the ! reduced row echelon form of A, and subtracting this from N. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 02 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns of ! the matrix A. ! ! Input, real ( kind = 8 ) A(M,N), the matrix to be analyzed. ! ! Output, integer ( kind = 4 ) NULLSPACE_SIZE, the estimated size ! of the nullspace. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n real ( kind = 8 ) a(m,n) integer ( kind = 4 ) i integer ( kind = 4 ) j integer ( kind = 4 ) leading integer ( kind = 4 ) nullspace_size real ( kind = 8 ) rref(m,n) ! ! Get the reduced row echelon form of A. ! rref(1:m,1:n) = a(1:m,1:n) call r8mat_rref ( m, n, rref ) ! ! Count the leading 1's in A. ! leading = 0 do i = 1, m do j = 1, n if ( rref(i,j) == 1.0D+00 ) then leading = leading + 1 exit end if end do end do nullspace_size = n - leading return end subroutine r8mat_rref ( m, n, a ) !*****************************************************************************80 ! !! R8MAT_RREF computes the reduced row echelon form of a matrix. ! ! Discussion: ! ! A matrix is in row echelon form if: ! ! * The first nonzero entry in each row is 1. ! ! * The leading 1 in a given row occurs in a column to ! the right of the leading 1 in the previous row. ! ! * Rows which are entirely zero must occur last. ! ! The matrix is in reduced row echelon form if, in addition to ! the first three conditions, it also satisfies: ! ! * Each column containing a leading 1 has no other nonzero entries. ! ! Example: ! ! Input matrix: ! ! 1.0 3.0 0.0 2.0 6.0 3.0 1.0 ! -2.0 -6.0 0.0 -2.0 -8.0 3.0 1.0 ! 3.0 9.0 0.0 0.0 6.0 6.0 2.0 ! -1.0 -3.0 0.0 1.0 0.0 9.0 3.0 ! ! Output matrix: ! ! 1.0 3.0 0.0 0.0 2.0 0.0 0.0 ! 0.0 0.0 0.0 1.0 2.0 0.0 0.0 ! 0.0 0.0 0.0 0.0 0.0 1.0 0.3 ! 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 02 October 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns of ! the matrix A. ! ! Input/output, real ( kind = 8 ) A(M,N). On input, the matrix to be ! analyzed. On output, the RREF form of the matrix. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n real ( kind = 8 ) a(m,n) integer ( kind = 4 ) i integer ( kind = 4 ) j integer ( kind = 4 ) lead integer ( kind = 4 ) r real ( kind = 8 ) temp lead = 1 do r = 1, m if ( n < lead ) then exit end if i = r do while ( a(i,lead) == 0.0 ) i = i + 1 if ( m < i ) then i = r lead = lead + 1 if ( n < lead ) then lead = -1 exit end if end if end do if ( lead < 0 ) then exit end if do j = 1, n temp = a(i,j) a(i,j) = a(r,j) a(r,j) = temp end do a(r,1:n) = a(r,1:n) / a(r,lead) do i = 1, m if ( i /= r ) then a(i,1:n) = a(i,1:n) - a(i,lead) * a(r,1:n) end if end do lead = lead + 1 end do return end subroutine r8vec_amax_index ( n, a, amax_index ) !*****************************************************************************80 ! !! R8VEC_AMAX_INDEX returns the index of the maximum absolute value in an R8VEC. ! ! Discussion: ! ! An R8VEC is a vector of R8's. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 30 January 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the number of entries in the array. ! ! Input, real ( kind = 8 ) A(N), the array. ! ! Output, integer ( kind = 4 ) AMAX_INDEX, the index of the entry of ! largest magnitude. ! implicit none integer ( kind = 4 ) n real ( kind = 8 ) a(n) real ( kind = 8 ) amax integer ( kind = 4 ) amax_index integer ( kind = 4 ) i if ( n <= 0 ) then amax_index = -1 else amax_index = 1 amax = abs ( a(1) ) do i = 2, n if ( amax < abs ( a(i) ) ) then amax_index = i amax = abs ( a(i) ) end if end do end if return end function r8vec_norm_l2 ( n, a ) !*****************************************************************************80 ! !! R8VEC_NORM_L2 returns the L2 norm of an R8VEC. ! ! Discussion: ! ! An R8VEC is a vector of R8 values. ! ! The vector L2 norm is defined as: ! ! R8VEC_NORM_L2 = sqrt ( sum ( 1 <= I <= N ) A(I)**2 ). ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 25 April 2002 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the number of entries in A. ! ! Input, real ( kind = 8 ) A(N), the vector whose L2 norm is desired. ! ! Output, real ( kind = 8 ) R8VEC_NORM_L2, the L2 norm of A. ! implicit none integer ( kind = 4 ) n real ( kind = 8 ) a(n) real ( kind = 8 ) r8vec_norm_l2 r8vec_norm_l2 = sqrt ( sum ( a(1:n)**2 ) ) return end function s_eqi ( s1, s2 ) !*****************************************************************************80 ! !! S_EQI is a case insensitive comparison of two strings for equality. ! ! Discussion: ! ! S_EQI ( 'Anjana', 'ANJANA' ) is TRUE. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 April 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) S1, S2, the strings to compare. ! ! Output, logical S_EQI, the result of the comparison. ! implicit none character c1 character c2 integer ( kind = 4 ) i integer ( kind = 4 ) lenc logical s_eqi character ( len = * ) s1 integer ( kind = 4 ) s1_length character ( len = * ) s2 integer ( kind = 4 ) s2_length s1_length = len ( s1 ) s2_length = len ( s2 ) lenc = min ( s1_length, s2_length ) s_eqi = .false. do i = 1, lenc c1 = s1(i:i) c2 = s2(i:i) call ch_cap ( c1 ) call ch_cap ( c2 ) if ( c1 /= c2 ) then return end if end do do i = lenc + 1, s1_length if ( s1(i:i) /= ' ' ) then return end if end do do i = lenc + 1, s2_length if ( s2(i:i) /= ' ' ) then return end if end do s_eqi = .true. return end subroutine sge_check ( lda, m, n, ierror ) !*****************************************************************************80 ! !! SGE_CHECK checks the dimensions of a general matrix. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 11 January 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) LDA, the leading dimension of the array. ! LDA must be at least M. ! ! Input, integer ( kind = 4 ) M, the number of rows of the matrix. ! M must be positive. ! ! Input, integer ( kind = 4 ) N, the number of columns of the matrix. ! N must be positive. ! ! Output, integer ( kind = 4 ) IERROR, reports whether any errors ! were detected. The default is IERROR = 0, but: ! IERROR = IERROR + 1 if LDA is illegal; ! IERROR = IERROR + 2 if M is illegal; ! IERROR = IERROR + 4 if N is illegal. ! implicit none integer ( kind = 4 ) ierror integer ( kind = 4 ) lda integer ( kind = 4 ) m integer ( kind = 4 ) n ierror = 0 if ( lda < m ) then ierror = ierror + 1 write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'SGE_CHECK - Fatal error!' write ( *, '(a,i8)' ) ' Illegal LDA = ', lda stop end if if ( m < 1 ) then ierror = ierror + 2 write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'SGE_CHECK - Fatal error!' write ( *, '(a,i8)' ) ' Illegal M = ', m stop end if if ( n < 1 ) then ierror = ierror + 4 write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'SGE_CHECK - Fatal error!' write ( *, '(a,i8)' ) ' Illegal N = ', n stop end if return end subroutine sge_fa ( lda, n, a, pivot, info ) !*****************************************************************************80 ! !! SGE_FA factors a general matrix. ! ! Discussion: ! ! SGE_FA is a simplified version of the LINPACK routine SGEFA. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 26 February 2001 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) LDA, the leading dimension of the array. ! LDA must be at least N. ! ! Input, integer ( kind = 4 ) N, the order of the matrix. ! N must be positive. ! ! Input/output, real ( kind = 8 ) A(LDA,N), the matrix to be factored. ! On output, A contains an upper triangular matrix and the multipliers ! which were used to obtain it. The factorization can be written ! A = L * U, where L is a product of permutation and unit lower ! triangular matrices and U is upper triangular. ! ! Output, integer ( kind = 4 ) PIVOT(N), a vector of pivot indices. ! ! Output, integer ( kind = 4 ) INFO, singularity flag. ! 0, no singularity detected. ! nonzero, the factorization failed on the INFO-th step. ! implicit none integer ( kind = 4 ) lda integer ( kind = 4 ) n real ( kind = 8 ) a(lda,n) integer ( kind = 4 ) i integer ( kind = 4 ) ierror integer ( kind = 4 ) info integer ( kind = 4 ) pivot(n) integer ( kind = 4 ) j integer ( kind = 4 ) k integer ( kind = 4 ) l real ( kind = 8 ) t ! ! Check the dimensions. ! call sge_check ( lda, n, n, ierror ) if ( ierror /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'SGE_FA - Fatal error!' write ( *, '(a)' ) ' Illegal dimensions.' stop end if info = 0 do k = 1, n - 1 ! ! Find L, the index of the pivot row. ! l = k do i = k + 1, n if ( abs ( a(l,k) ) < abs ( a(i,k) ) ) then l = i end if end do pivot(k) = l ! ! If the pivot index is zero, the algorithm has failed. ! if ( a(l,k) == 0.0D+00 ) then info = k write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'SGE_FA - Fatal error!' write ( *, '(a,i8)' ) ' Zero pivot on step ', info return end if ! ! Interchange rows L and K if necessary. ! if ( l /= k ) then call r8_swap ( a(l,k), a(k,k) ) end if ! ! Normalize the values that lie below the pivot entry A(K,K). ! a(k+1:n,k) = -a(k+1:n,k) / a(k,k) ! ! Row elimination with column indexing. ! do j = k + 1, n if ( l /= k ) then call r8_swap ( a(l,j), a(k,j) ) end if a(k+1:n,j) = a(k+1:n,j) + a(k+1:n,k) * a(k,j) end do end do pivot(n) = n if ( a(n,n) == 0.0D+00 ) then info = n write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'SGE_FA - Fatal error!' write ( *, '(a,i8)' ) ' Zero pivot on step ', info end if return end subroutine sge_sl ( lda, n, a, pivot, b, job ) !*****************************************************************************80 ! !! SGE_SL solves a system factored by SGE_FA. ! ! Discussion: ! ! SGE_SL is a simplified version of the LINPACK routine SGESL. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 04 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) LDA, the leading dimension of the array. ! LDA must be at least N. ! ! Input, integer ( kind = 4 ) N, the order of the matrix. ! N must be positive. ! ! Input, real ( kind = 8 ) A(LDA,N), the LU factors from SGE_FA. ! ! Input, integer ( kind = 4 ) PIVOT(N), the pivot vector from SGE_FA. ! ! Input/output, real ( kind = 8 ) B(N). ! On input, the right hand side vector. ! On output, the solution vector. ! ! Input, integer ( kind = 4 ) JOB, specifies the operation. ! 0, solve A * x = b. ! nonzero, solve transpose ( A ) * x = b. ! implicit none integer ( kind = 4 ) lda integer ( kind = 4 ) n real ( kind = 8 ) a(lda,n) real ( kind = 8 ) b(n) integer ( kind = 4 ) ierror integer ( kind = 4 ) pivot(n) integer ( kind = 4 ) j integer ( kind = 4 ) job integer ( kind = 4 ) k integer ( kind = 4 ) l real ( kind = 8 ) t ! ! Check the dimensions. ! call sge_check ( lda, n, n, ierror ) if ( ierror /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'SGE_SL - Fatal error!' write ( *, '(a)' ) ' Illegal dimensions.' stop end if ! ! Solve A * x = b. ! if ( job == 0 ) then ! ! Solve PL * Y = B. ! do k = 1, n - 1 l = pivot(k) if ( l /= k ) then call r8_swap ( b(l), b(k) ) end if b(k+1:n) = b(k+1:n) + a(k+1:n,k) * b(k) end do ! ! Solve U * X = Y. ! do k = n, 1, -1 b(k) = b(k) / a(k,k) b(1:k-1) = b(1:k-1) - a(1:k-1,k) * b(k) end do ! ! Solve transpose ( A ) * X = B. ! else ! ! Solve transpose ( U ) * Y = B. ! do k = 1, n b(k) = ( b(k) - dot_product ( b(1:k-1), a(1:k-1,k) ) ) / a(k,k) end do ! ! Solve transpose ( PL ) * X = Y. ! do k = n - 1, 1, -1 b(k) = b(k) + dot_product ( b(k+1:n), a(k+1:n,k) ) l = pivot(k) if ( l /= k ) then call r8_swap ( b(l), b(k) ) end if end do end if return end subroutine timestamp ( ) !*****************************************************************************80 ! !! TIMESTAMP prints the current YMDHMS date as a time stamp. ! ! Example: ! ! 31 May 2001 9:45:54.872 AM ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 18 May 2013 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! None ! implicit none character ( len = 8 ) ampm integer ( kind = 4 ) d integer ( kind = 4 ) h integer ( kind = 4 ) m integer ( kind = 4 ) mm character ( len = 9 ), parameter, dimension(12) :: month = (/ & 'January ', 'February ', 'March ', 'April ', & 'May ', 'June ', 'July ', 'August ', & 'September', 'October ', 'November ', 'December ' /) integer ( kind = 4 ) n integer ( kind = 4 ) s integer ( kind = 4 ) values(8) integer ( kind = 4 ) y call date_and_time ( values = values ) y = values(1) m = values(2) d = values(3) h = values(5) n = values(6) s = values(7) mm = values(8) if ( h < 12 ) then ampm = 'AM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Noon' else ampm = 'PM' end if else h = h - 12 if ( h < 12 ) then ampm = 'PM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Midnight' else ampm = 'AM' end if end if end if write ( *, '(i2.2,1x,a,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) & d, trim ( month(m) ), y, h, ':', n, ':', s, '.', mm, trim ( ampm ) return end subroutine zero_rc ( a, b, t, arg, status, value ) !*****************************************************************************80 ! !! ZERO_RC seeks the root of a function F(X) using reverse communication. ! ! Discussion: ! ! The interval [A,B] must be a change of sign interval for F. ! That is, F(A) and F(B) must be of opposite signs. Then ! assuming that F is continuous implies the existence of at least ! one value C between A and B for which F(C) = 0. ! ! The location of the zero is determined to within an accuracy ! of 6 * MACHEPS * abs ( C ) + 2 * T. ! ! The routine is a revised version of the Brent zero finder ! algorithm, using reverse communication. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 October 2008 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Richard Brent, ! Algorithms for Minimization Without Derivatives, ! Dover, 2002, ! ISBN: 0-486-41998-3, ! LC: QA402.5.B74. ! ! Parameters: ! ! Input, real ( kind = 8 ) A, B, the endpoints of the change of ! sign interval. ! ! Input, real ( kind = 8 ) T, a positive error tolerance. ! ! Output, real ( kind = 8 ) ARG, the currently considered point. The user ! does not need to initialize this value. On return with STATUS positive, ! the user is requested to evaluate the function at ARG, and return ! the value in VALUE. On return with STATUS zero, ARG is the routine's ! estimate for the function's zero. ! ! Input/output, integer ( kind = 4 ) STATUS, used to communicate between ! the user and the routine. The user only sets STATUS to zero on the first ! call, to indicate that this is a startup call. The routine returns STATUS ! positive to request that the function be evaluated at ARG, or returns ! STATUS as 0, to indicate that the iteration is complete and that ! ARG is the estimated zero ! ! Input, real ( kind = 8 ) VALUE, the function value at ARG, as requested ! by the routine on the previous call. ! implicit none real ( kind = 8 ) a real ( kind = 8 ) arg real ( kind = 8 ) b real ( kind = 8 ), save :: c real ( kind = 8 ), save :: d real ( kind = 8 ), save :: e real ( kind = 8 ), save :: fa real ( kind = 8 ), save :: fb real ( kind = 8 ), save :: fc real ( kind = 8 ) m real ( kind = 8 ), save :: machep real ( kind = 8 ) p real ( kind = 8 ) q real ( kind = 8 ) r real ( kind = 8 ) s real ( kind = 8 ), save :: sa real ( kind = 8 ), save :: sb integer ( kind = 4 ) status real ( kind = 8 ) t real ( kind = 8 ) tol real ( kind = 8 ) value ! ! Input STATUS = 0. ! Initialize, request F(A). ! if ( status == 0 ) then machep = epsilon ( a ) sa = a sb = b e = sb - sa d = e status = 1 arg = a return ! ! Input STATUS = 1. ! Receive F(A), request F(B). ! else if ( status == 1 ) then fa = value status = 2 arg = sb return ! ! Input STATUS = 2 ! Receive F(B). ! else if ( status == 2 ) then fb = value if ( 0.0D+00 < fa * fb ) then status = -1 return end if c = sa fc = fa else fb = value if ( ( 0.0D+00 < fb .and. 0.0D+00 < fc ) .or. & ( fb <= 0.0D+00 .and. fc <= 0.0D+00 ) ) then c = sa fc = fa e = sb - sa d = e end if end if ! ! Compute the next point at which a function value is requested. ! if ( abs ( fc ) < abs ( fb ) ) then sa = sb sb = c c = sa fa = fb fb = fc fc = fa end if tol = 2.0D+00 * machep * abs ( sb ) + t m = 0.5D+00 * ( c - sb ) if ( abs ( m ) <= tol .or. fb == 0.0D+00 ) then status = 0 arg = sb return end if if ( abs ( e ) < tol .or. abs ( fa ) <= abs ( fb ) ) then e = m d = e else s = fb / fa if ( sa == c ) then p = 2.0D+00 * m * s q = 1.0D+00 - s else q = fa / fc r = fb / fc p = s * ( 2.0D+00 * m * a * ( q - r ) - ( sb - sa ) * ( r - 1.0D+00 ) ) q = ( q - 1.0D+00 ) * ( r - 1.0D+00 ) * ( s - 1.0D+00 ) end if if ( 0.0D+00 < p ) then q = - q else p = - p end if s = e e = d if ( 2.0D+00 * p < 3.0D+00 * m * q - abs ( tol * q ) .and. & p < abs ( 0.5D+00 * s * q ) ) then d = p / q else e = m d = e end if end if sa = sb fa = fb if ( tol < abs ( d ) ) then sb = sb + d else if ( 0.0D+00 < m ) then sb = sb + tol else sb = sb - tol end if arg = sb status = status + 1 return end