ETS  \$Id: Doxyfile 2162 2020-02-26 14:16:09Z g2dpc $
 All Classes Files Functions Variables Pages
solve_cubic.f90
Go to the documentation of this file.
1 subroutine solve_cubic(c0, c1, c2, c3, x1, x2, x3, ifail)
2 !-----------------------------------------------------------------------
3 ! solves a cubic equation with a solution with -1.< x < 1
4 ! cn : the coefficient of x**n, x : the real solution with -1.< x < 1.
5 !-----------------------------------------------------------------------
6 
7  use itm_types
8  use math_functions, only : root
9 
10  implicit none
11 
12  real(r8), intent(in) :: c0, c1, c2, c3
13 
14  real(r8), intent(out) :: x1, x2, x3
15  integer(itm_i4), intent(out) :: ifail
16 
17  real(r8) :: tol
18  real(r8) :: aa, bb, cc, det
19  real(r8) :: pi
20  real(r8) :: a0, a1, a2
21  real(r8) :: p, q
22  real(r8) :: u, v
23  real(r8) :: angle, dum
24 
25  x1 = 99._r8
26  x2 = 999._r8
27  x3 = 9999._r8
28  tol = 1.e-8_r8
29  ifail = 0
30 !------------------------------------- 2nd order poly for small c3
31  if (abs(c3) / (abs(c1) + abs(c2) + abs(c3)) < 1.e-9_r8) then
32  aa = c2
33  bb = c1
34  cc = c0
35  det = bb**2 - 4._r8 * aa * cc
36  if (det > 0._r8) then
37  x1 = root(aa, bb, cc, det, 1._r8)
38  if (abs(x1) > 1._r8 + tol) then
39  x1 = root(aa, bb, cc, det, -1._r8)
40  end if
41  else
42  ifail = 1
43  end if
44  else
45 !------------------------------------- 3rd order poly solution
46  pi = 2._r8 * asin(1._r8)
47  a0 = c0 / c3
48  a1 = c1 / c3
49  a2 = c2 / c3
50  p = -(a2**2) / 3._r8 + a1
51  q = 2._r8 / 27._r8 * (a2**3) - a2 * a1 / 3._r8 + a0
52  det = (p / 3._r8)**3 + (q / 2._r8)**2
53  if (det > 0._r8) then
54  u = sign(1._r8, -q / 2._r8 + sqrt(det)) * abs(-q / 2._r8 &
55  + sqrt(det))**(1._r8 / 3._r8)
56  v = sign(1._r8, -q / 2._r8 - sqrt(det)) * abs(-q / 2._r8 &
57  - sqrt(det))**(1._r8 / 3._r8)
58  x1 = u + v - a2 / 3._r8
59  if (abs(x1) >= 1._r8 + tol) ifail = 1
60  else
61  p = -p
62  angle = sign(1._r8, p) * acos((q / 2._r8) / sqrt(abs(p) &
63  / 3._r8)**3)
64  x1 = -2._r8 * sqrt(abs(p) / 3._r8) * cos(angle / 3._r8) &
65  - a2 / 3._r8
66  x2 = -2._r8 * sqrt(abs(p) / 3._r8) * cos(2._r8 * pi &
67  / 3._r8 - angle / 3._r8) - a2 / 3._r8
68  x3 = -2._r8 * sqrt(abs(p) / 3._r8) * cos(2._r8 * pi &
69  / 3._r8 + angle / 3._r8) - a2 / 3._r8
70  end if
71  if (abs(x1) > abs(x2)) then
72  dum = x1
73  x1 = x2
74  x2 = dum
75  end if
76  if (abs(x2) > abs(x3)) then
77  dum = x2
78  x2 = x3
79  x3 = dum
80  end if
81  if (abs(x1) > abs(x2)) then
82  dum = x1
83  x1 = x2
84  x2 = dum
85  end if
86  end if
87  if (abs(x1) > 1._r8 + tol) ifail = 1
88 
89  return
90 end subroutine solve_cubic
subroutine solve_cubic(c0, c1, c2, c3, x1, x2, x3, ifail)
Definition: solve_cubic.f90:1
real(r8) function, public root(a, b, c, d, sgn)
real(r8) function p(a, x, xr, xs, yr, ys, psi, psir, F_dia)