!>
!> @file difequ.f90
!>
!> @brief
!>
!> @copyright
!> Copyright (©) 2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
!> SPC (Swiss Plasma Center)
!>
!> SPClibs is free software: you can redistribute it and/or modify it under
!> the terms of the GNU Lesser General Public License as published by the Free
!> Software Foundation, either version 3 of the License, or (at your option)
!> any later version.
!>
!> SPClibs is distributed in the hope that it will be useful, but WITHOUT ANY
!> WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
!> FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
!>
!> You should have received a copy of the GNU Lesser General Public License
!> along with this program. If not, see .
!>
!> @authors
!> (in alphabetical order)
!> @author Trach-Minh Tran
!>
subroutine difequ ( mode, xx, v )
!*************************************************************************
!
!! DIFEQU returns information about a differential equation.
!
! Reference:
!
! Carl DeBoor,
! A Practical Guide to Splines,
! Springer Verlag.
!
! Parameters:
!
! Input, integer MODE, an integer indicating the task to be performed.
! 1, initialization
! 2, evaluate de at xx
! 3, specify the next side condition
! 4, analyze the approximation
!
! Input, real ( kind = 8 ) XX, a point at which information is wanted
!
! Output, real ( kind = 8 ) V, depends on the MODE. See comments below
!
implicit none
integer, parameter :: npiece = 100
integer, parameter :: ncoef = 2000
real ( kind = 8 ) break
real ( kind = 8 ) coef
real ( kind = 8 ) eps
real ( kind = 8 ) ep1
real ( kind = 8 ) ep2
real ( kind = 8 ) error
real ( kind = 8 ) factor
integer i
integer iside
integer itermx
integer k
integer kpm
integer l
integer m
integer mode
real ( kind = 8 ) rho
real ( kind = 8 ) s2ovep
real ( kind = 8 ) solutn
real ( kind = 8 ) un
real ( kind = 8 ) v(20)
real ( kind = 8 ) value
real ( kind = 8 ) x
real ( kind = 8 ) xside
real ( kind = 8 ) xx
common /approx/ break(npiece),coef(ncoef),l,kpm
common /side/ m,iside,xside(10)
common /other/ itermx,k,rho(19)
!
! This sample of DIFEQU is for the example in chapter xv. It is a
! nonlinear second order two point boundary value problem.
!
go to (10,50,60,110), mode
!
! Initialize everything, Set the order M of the differential equation,
! the nondecreasing sequence xside(i),i=1,...,m, of points at which side
! conditions are given and anything else necessary.
!
10 continue
m = 2
xside(1) = 0.0D+00
xside(2) = 1.0D+00
!
! Print out heading.
!
write ( *, * ) ' '
write ( *, * ) ' Carrier''s nonlinear perturb. problem'
write ( *, * ) ' '
eps = 0.005D+00
write(*,*)'EPS = ',eps
!
! Set constants used in formula for solution below.
!
factor = ( sqrt ( 2.0D+00 ) + sqrt ( 3.0D+00 ) )**2
s2ovep = sqrt ( 2.0D+00 / eps )
!
! Initial guess for Newton iteration. un(x)=x*x-1.
!
l = 1
break(1) = 0.0D+00
do i = 1, kpm
coef(i) = 0.0D+00
end do
coef(1) = -1.0D+00
coef(3) = 2.0D+00
itermx = 10
return
!
! Provide value of left side coefficients and right side at xx .
! specifically, at xx the dif.equ. reads:
!
! v(m+1)d**m+v(m)d**(m-1) + ... + v(1)d**0 = v(m+2)
!
! in terms of the quantities v(i),i=1,...,m+2, to be computed here.
!
50 continue
v(3) = eps
v(2) = 0.0D+00
call ppvalu(break,coef,l,kpm,xx,0,un)
v(1) = 2.0D+00 * un
v(4) = un**2 + 1.0D+00
return
!
! provide the M side conditions. these conditions are of the form
! v(m+1)d**m+v(m)d**(m-1) + ... + v(1)d**0 = v(m+2)
! in terms of the quantities v(i),i=1,...,m+2, to be specified here.
! note that v(m+1)=0 for customary side conditions.
!
60 continue
v(m+1) = 0.0D+00
if ( iside == 1 ) then
v(2) = 1.0D+00
v(1) = 0.0D+00
v(4) = 0.0D+00
iside = iside+1
else if ( iside == 2 ) then
v(2) = 0.0D+00
v(1) = 1.0D+00
v(4) = 0.0D+00
iside = iside + 1
end if
return
!
! Calculate the error near the boundary layer at 1.
!
110 continue
write(*,*)' '
write(*,*)' X, G(X) and G(X)-F(X) at selected points:'
write(*,*)' '
x = 0.75D+00
do i = 1, 9
ep1 = exp ( s2ovep * ( 1.0D+00 - x ) ) * factor
ep2 = exp ( s2ovep * ( 1.0D+00 + x ) ) * factor
solutn = 12.0D+00 / ( 1.0D+00 + ep1 )**2 * ep1 &
+12.0D+00 / ( 1.0D+00 + ep2 )**2 * ep2 - 1.0D+00
call ppvalu(break,coef,l,kpm,x,0,value)
error = solutn-value
write ( *, '(1x,3g14.6)' ) x, solutn, error
x = x+0.03125
end do
return
end