6 use regrid_solvers,
only : solve_linear_system, solve_tridiagonal_system
9 implicit none ;
private
14 public bound_edge_values
15 public average_discontinuous_edge_values
16 public check_discontinuous_edge_values
17 public edge_values_explicit_h2
18 public edge_values_explicit_h4
19 public edge_values_implicit_h4
20 public edge_values_implicit_h6
22 #undef __DO_SAFETY_CHECKS__
29 real,
parameter :: hneglect_edge_dflt = 1.e-10
31 real,
parameter :: hneglect_dflt = 1.e-30
33 real,
parameter :: hminfrac = 1.e-5
47 subroutine bound_edge_values( N, h, u, edge_val, h_neglect )
48 integer,
intent(in) :: n
49 real,
dimension(:),
intent(in) :: h
50 real,
dimension(:),
intent(in) :: u
51 real,
dimension(:,:),
intent(inout) :: edge_val
53 real,
optional,
intent(in) :: h_neglect
61 real :: sigma_l, sigma_c, sigma_r
67 hneglect = hneglect_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
81 elseif ( k == n )
then
103 sigma_l = 2.0 * ( u_c - u_l ) / ( h_c + hneglect )
104 sigma_c = 2.0 * ( u_r - u_l ) / ( h_l + 2.0*h_c + h_r + hneglect )
105 sigma_r = 2.0 * ( u_r - u_c ) / ( h_c + hneglect )
107 if ( (sigma_l * sigma_r) > 0.0 )
then
108 slope = sign( min(abs(sigma_l),abs(sigma_c),abs(sigma_r)), sigma_c )
117 slope = slope * h_c * 0.5
119 if ( (u_l-u0_l)*(u0_l-u_c) < 0.0 )
then
120 u0_l = u_c - sign( min( abs(slope), abs(u0_l-u_c) ), slope )
123 if ( (u_r-u0_r)*(u0_r-u_c) < 0.0 )
then
124 u0_r = u_c + sign( min( abs(slope), abs(u0_r-u_c) ), slope )
128 u0_l = max( min( u0_l, max(u_l, u_c) ), min(u_l, u_c) )
129 u0_r = max( min( u0_r, max(u_r, u_c) ), min(u_r, u_c) )
137 end subroutine bound_edge_values
143 subroutine average_discontinuous_edge_values( N, edge_val )
144 integer,
intent(in) :: n
145 real,
dimension(:,:),
intent(inout) :: edge_val
157 u0_minus = edge_val(k,2)
160 u0_plus = edge_val(k+1,1)
162 if ( u0_minus /= u0_plus )
then
163 u0_avg = 0.5 * ( u0_minus + u0_plus )
164 edge_val(k,2) = u0_avg
165 edge_val(k+1,1) = u0_avg
170 end subroutine average_discontinuous_edge_values
176 subroutine check_discontinuous_edge_values( N, u, edge_val )
177 integer,
intent(in) :: n
178 real,
dimension(:),
intent(in) :: u
179 real,
dimension(:,:),
intent(inout) :: edge_val
192 u0_minus = edge_val(k,2)
195 u0_plus = edge_val(k+1,1)
203 if ( (u0_plus - u0_minus)*(um_plus - um_minus) < 0.0 )
then
204 u0_avg = 0.5 * ( u0_minus + u0_plus )
205 u0_avg = max( min( u0_avg, max(um_minus, um_plus) ), min(um_minus, um_plus) )
206 edge_val(k,2) = u0_avg
207 edge_val(k+1,1) = u0_avg
212 end subroutine check_discontinuous_edge_values
228 subroutine edge_values_explicit_h2( N, h, u, edge_val, h_neglect )
229 integer,
intent(in) :: n
230 real,
dimension(:),
intent(in) :: h
231 real,
dimension(:),
intent(in) :: u
232 real,
dimension(:,:),
intent(inout) :: edge_val
234 real,
optional,
intent(in) :: h_neglect
241 hneglect = hneglect_edge_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
259 edge_val(k,1) = ( u0*h1 + u1*h0 ) / ( h0 + h1 )
263 edge_val(k-1,2) = edge_val(k,1)
271 end subroutine edge_values_explicit_h2
292 subroutine edge_values_explicit_h4( N, h, u, edge_val, h_neglect )
293 integer,
intent(in) :: n
294 real,
dimension(:),
intent(in) :: h
295 real,
dimension(:),
intent(in) :: u
296 real,
dimension(:,:),
intent(inout) :: edge_val
298 real,
optional,
intent(in) :: h_neglect
301 real :: u0, u1, u2, u3
302 real :: h0, h1, h2, h3
305 real,
dimension(5) :: x
306 real,
dimension(4,4) :: a
307 real,
dimension(4) :: b, c
310 hneglect = hneglect_edge_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
321 if (h0+h1==0. .or. h1+h2==0. .or. h2+h3==0.)
then
322 f1 = max( hneglect, h0+h1+h2+h3 )
323 h0 = max( hminfrac*f1, h(i-2) )
324 h1 = max( hminfrac*f1, h(i-1) )
325 h2 = max( hminfrac*f1, h(i) )
326 h3 = max( hminfrac*f1, h(i+1) )
334 f1 = (h0+h1) * (h2+h3) / (h1+h2)
335 f2 = u1 * h2 + u2 * h1
336 f3 = 1.0 / (h0+h1+h2) + 1.0 / (h1+h2+h3)
340 f1 = h2 * (h2+h3) / ( (h0+h1+h2)*(h0+h1) )
341 f2 = u1*(h0+2.0*h1) - u0*h1
345 f1 = h1 * (h0+h1) / ( (h1+h2+h3)*(h2+h3) )
346 f2 = u2*(2.0*h2+h3) - u3*h2
350 e = e / ( h0 + h1 + h2 + h3)
355 #ifdef __DO_SAFETY_CHECKS__
357 write(0,*)
'NaN in explicit_edge_h4 at k=',i
358 write(0,*)
'u0-u3=',u0,u1,u2,u3
359 write(0,*)
'h0-h3=',h0,h1,h2,h3
360 write(0,*)
'f1-f3=',f1,f2,f3
361 stop
'Nan during edge_values_explicit_h4'
368 f1 = max( hneglect, hminfrac*sum(h(1:4)) )
371 x(i) = x(i-1) + max(f1, h(i-1))
377 a(i,j) = ( (x(i+1)**j) - (x(i)**j) ) / real(j)
380 b(i) = u(i) * max(f1, h(i) )
384 call solve_linear_system( a, b, c, 4 )
387 edge_val(1,1) = evaluation_polynomial( c, 4, x(1) )
390 edge_val(1,2) = evaluation_polynomial( c, 4, x(2) )
391 edge_val(2,1) = edge_val(1,2)
393 #ifdef __DO_SAFETY_CHECKS__
394 if (edge_val(1,1) /= edge_val(1,1) .or. edge_val(1,2) /= edge_val(1,2))
then
395 write(0,*)
'NaN in explicit_edge_h4 at k=',1
399 write(0,*)
'h(1:4)=',h(1:4)
401 stop
'Nan during edge_values_explicit_h4'
406 f1 = max( hneglect, hminfrac*sum(h(n-3:n)) )
409 x(i) = x(i-1) + max(f1, h(n-5+i))
415 a(i,j) = ( (x(i+1)**j) - (x(i)**j) ) / real(j)
418 b(i) = u(n-4+i) * max(f1, h(n-4+i) )
422 call solve_linear_system( a, b, c, 4 )
425 edge_val(n,2) = evaluation_polynomial( c, 4, x(5) )
428 edge_val(n,1) = evaluation_polynomial( c, 4, x(4) )
429 edge_val(n-1,2) = edge_val(n,1)
431 #ifdef __DO_SAFETY_CHECKS__
432 if (edge_val(n,1) /= edge_val(n,1) .or. edge_val(n,2) /= edge_val(n,2))
then
433 write(0,*)
'NaN in explicit_edge_h4 at k=',n
437 a(i,j) = ( (x(i+1)**j) - (x(i)**j) ) / real(j)
440 b(i) = u(n-4+i) * ( h(n-4+i) )
444 write(0,*)
'h(:N)=',h(n-3:n)
446 stop
'Nan during edge_values_explicit_h4'
450 end subroutine edge_values_explicit_h4
478 subroutine edge_values_implicit_h4( N, h, u, edge_val, h_neglect )
479 integer,
intent(in) :: n
480 real,
dimension(:),
intent(in) :: h
481 real,
dimension(:),
intent(in) :: u
482 real,
dimension(:,:),
intent(inout) :: edge_val
484 real,
optional,
intent(in) :: h_neglect
488 real :: h0_2, h1_2, h0h1
492 real,
dimension(5) :: x
493 real,
dimension(4,4) :: asys
494 real,
dimension(4) :: bsys, csys
495 real,
dimension(N+1) :: tri_l, &
502 hneglect = hneglect_edge_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
527 a = 2.0 * h1_2 * ( h1_2 + 2.0 * h0_2 + 3.0 * h0h1 ) / d4
528 b = 2.0 * h0_2 * ( h0_2 + 2.0 * h1_2 + 3.0 * h0h1 ) / d4
534 tri_b(i+1) = a * u(i) + b * u(i+1)
539 h0 = max( hneglect, hminfrac*sum(h(1:4)) )
542 x(i) = x(i-1) + max( h0, h(i-1) )
548 asys(i,j) = ( (x(i+1)**j) - (x(i)**j) ) / j
551 bsys(i) = u(i) * max( h0, h(i) )
555 call solve_linear_system( asys, bsys, csys, 4 )
559 tri_b(1) = evaluation_polynomial( csys, 4, x(1) )
562 h0 = max( hneglect, hminfrac*sum(h(n-3:n)) )
565 x(i) = x(i-1) + max( h0, h(n-5+i) )
571 asys(i,j) = ( (x(i+1)**j) - (x(i)**j) ) / j
574 bsys(i) = u(n-4+i) * max( h0, h(n-4+i) )
578 call solve_linear_system( asys, bsys, csys, 4 )
582 tri_b(n+1) = evaluation_polynomial( csys, 4, x(5) )
585 call solve_tridiagonal_system( tri_l, tri_d, tri_u, tri_b, tri_x, n+1 )
588 edge_val(i,1) = tri_x(i)
589 edge_val(i-1,2) = tri_x(i)
591 edge_val(1,1) = tri_x(1)
592 edge_val(n,2) = tri_x(n+1)
594 end subroutine edge_values_implicit_h4
631 subroutine edge_values_implicit_h6( N, h, u, edge_val, h_neglect )
632 integer,
intent(in) :: n
633 real,
dimension(:),
intent(in) :: h
634 real,
dimension(:),
intent(in) :: u
635 real,
dimension(:,:),
intent(inout) :: edge_val
637 real,
optional,
intent(in) :: h_neglect
640 real :: h0, h1, h2, h3
642 real :: g_4, g_5, g_6
643 real :: d2, d3, d4, d5, d6
644 real :: n2, n3, n4, n5, n6
650 real :: h0ph1, h0ph1_2
651 real :: h0ph1_3, h0ph1_4
652 real :: h2ph3, h2ph3_2
653 real :: h2ph3_3, h2ph3_4
654 real :: h0ph1_5, h2ph3_5
657 real,
dimension(7) :: x
658 real,
dimension(6,6) :: asys
659 real,
dimension(6) :: bsys, csys
660 real,
dimension(N+1) :: tri_l, &
667 hneglect = hneglect_edge_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
680 g = max( hneglect, h0+h1+h2+h3 )
681 h0 = max( hminfrac*g, h0 )
682 h1 = max( hminfrac*g, h1 )
683 h2 = max( hminfrac*g, h2 )
684 h3 = max( hminfrac*g, h3 )
707 d2 = ( h1_2 - g_2 ) / h0
708 d3 = ( h1_3 - g_3 ) / h0
709 d4 = ( h1_4 - g_4 ) / h0
710 d5 = ( h1_5 - g_5 ) / h0
711 d6 = ( h1_6 - g_6 ) / h0
720 n2 = ( g_2 - h2_2 ) / h3
721 n3 = ( g_3 - h2_3 ) / h3
722 n4 = ( g_4 - h2_4 ) / h3
723 n5 = ( g_5 - h2_5 ) / h3
724 n6 = ( g_6 - h2_6 ) / h3
736 asys(2,3) = -0.5 * d2
738 asys(2,5) = -0.5 * h2
739 asys(2,6) = -0.5 * n2
741 asys(3,1) = 0.5 * h1_2
742 asys(3,2) = 0.5 * h2_2
744 asys(3,4) = - h1_2 / 6.0
745 asys(3,5) = - h2_2 / 6.0
746 asys(3,6) = - n3 / 6.0
748 asys(4,1) = - h1_3 / 6.0
749 asys(4,2) = h2_3 / 6.0
750 asys(4,3) = - d4 / 24.0
751 asys(4,4) = h1_3 / 24.0
752 asys(4,5) = - h2_3 / 24.0
753 asys(4,6) = - n4 / 24.0
755 asys(5,1) = h1_4 / 24.0
756 asys(5,2) = h2_4 / 24.0
757 asys(5,3) = d5 / 120.0
758 asys(5,4) = - h1_4 / 120.0
759 asys(5,5) = - h2_4 / 120.0
760 asys(5,6) = - n5 / 120.0
762 asys(6,1) = - h1_5 / 120.0
763 asys(6,2) = h2_5 / 120.0
764 asys(6,3) = - d6 / 720.0
765 asys(6,4) = h1_5 / 720.0
766 asys(6,5) = - h2_5 / 720.0
767 asys(6,6) = - n6 / 720.0
769 bsys(:) = (/ -1.0, 0.0, 0.0, 0.0, 0.0, 0.0 /)
771 call solve_linear_system( asys, bsys, csys, 6 )
783 tri_b(k+1) = a * u(k-1) + b * u(k) + c * u(k+1) + d * u(k+2)
797 g = max( hneglect, h0+h1+h2+h3 )
798 h0 = max( hminfrac*g, h0 )
799 h1 = max( hminfrac*g, h1 )
800 h2 = max( hminfrac*g, h2 )
801 h3 = max( hminfrac*g, h3 )
825 h0ph1_2 = h0ph1 * h0ph1
826 h0ph1_3 = h0ph1_2 * h0ph1
827 h0ph1_4 = h0ph1_2 * h0ph1_2
828 h0ph1_5 = h0ph1_3 * h0ph1_2
830 d2 = ( h1_2 - g_2 ) / h0
831 d3 = ( h1_3 - g_3 ) / h0
832 d4 = ( h1_4 - g_4 ) / h0
833 d5 = ( h1_5 - g_5 ) / h0
834 d6 = ( h1_6 - g_6 ) / h0
843 n2 = ( g_2 - h2_2 ) / h3
844 n3 = ( g_3 - h2_3 ) / h3
845 n4 = ( g_4 - h2_4 ) / h3
846 n5 = ( g_5 - h2_5 ) / h3
847 n6 = ( g_6 - h2_6 ) / h3
859 asys(2,3) = -0.5 * d2
861 asys(2,5) = -0.5 * h2
862 asys(2,6) = -0.5 * n2
864 asys(3,1) = 0.5 * h0ph1_2
867 asys(3,4) = - h1_2 / 6.0
868 asys(3,5) = - h2_2 / 6.0
869 asys(3,6) = - n3 / 6.0
871 asys(4,1) = - h0ph1_3 / 6.0
873 asys(4,3) = - d4 / 24.0
874 asys(4,4) = h1_3 / 24.0
875 asys(4,5) = - h2_3 / 24.0
876 asys(4,6) = - n4 / 24.0
878 asys(5,1) = h0ph1_4 / 24.0
880 asys(5,3) = d5 / 120.0
881 asys(5,4) = - h1_4 / 120.0
882 asys(5,5) = - h2_4 / 120.0
883 asys(5,6) = - n5 / 120.0
885 asys(6,1) = - h0ph1_5 / 120.0
887 asys(6,3) = - d6 / 720.0
888 asys(6,4) = h1_5 / 720.0
889 asys(6,5) = - h2_5 / 720.0
890 asys(6,6) = - n6 / 720.0
892 bsys(:) = (/ -1.0, h1, -0.5*h1_2, h1_3/6.0, -h1_4/24.0, h1_5/120.0 /)
894 call solve_linear_system( asys, bsys, csys, 6 )
906 tri_b(2) = a * u(1) + b * u(2) + c * u(3) + d * u(4)
909 g = max( hneglect, hminfrac*sum(h(1:6)) )
912 x(i) = x(i-1) + max( g, h(i-1) )
918 asys(i,j) = ( (x(i+1)**j) - (x(i)**j) ) / j
921 bsys(i) = u(i) * max( g, h(i) )
925 call solve_linear_system( asys, bsys, csys, 6 )
930 tri_b(1) = evaluation_polynomial( csys, 6, x(1) )
942 g = max( hneglect, h0+h1+h2+h3 )
943 h0 = max( hminfrac*g, h0 )
944 h1 = max( hminfrac*g, h1 )
945 h2 = max( hminfrac*g, h2 )
946 h3 = max( hminfrac*g, h3 )
970 h2ph3_2 = h2ph3 * h2ph3
971 h2ph3_3 = h2ph3_2 * h2ph3
972 h2ph3_4 = h2ph3_2 * h2ph3_2
973 h2ph3_5 = h2ph3_3 * h2ph3_2
975 d2 = ( h1_2 - g_2 ) / h0
976 d3 = ( h1_3 - g_3 ) / h0
977 d4 = ( h1_4 - g_4 ) / h0
978 d5 = ( h1_5 - g_5 ) / h0
979 d6 = ( h1_6 - g_6 ) / h0
988 n2 = ( g_2 - h2_2 ) / h3
989 n3 = ( g_3 - h2_3 ) / h3
990 n4 = ( g_4 - h2_4 ) / h3
991 n5 = ( g_5 - h2_5 ) / h3
992 n6 = ( g_6 - h2_6 ) / h3
1004 asys(2,3) = -0.5 * d2
1005 asys(2,4) = 0.5 * h1
1006 asys(2,5) = -0.5 * h2
1007 asys(2,6) = -0.5 * n2
1010 asys(3,2) = 0.5 * h2ph3_2
1011 asys(3,3) = d3 / 6.0
1012 asys(3,4) = - h1_2 / 6.0
1013 asys(3,5) = - h2_2 / 6.0
1014 asys(3,6) = - n3 / 6.0
1017 asys(4,2) = h2ph3_3 / 6.0
1018 asys(4,3) = - d4 / 24.0
1019 asys(4,4) = h1_3 / 24.0
1020 asys(4,5) = - h2_3 / 24.0
1021 asys(4,6) = - n4 / 24.0
1024 asys(5,2) = h2ph3_4 / 24.0
1025 asys(5,3) = d5 / 120.0
1026 asys(5,4) = - h1_4 / 120.0
1027 asys(5,5) = - h2_4 / 120.0
1028 asys(5,6) = - n5 / 120.0
1031 asys(6,2) = h2ph3_5 / 120.0
1032 asys(6,3) = - d6 / 720.0
1033 asys(6,4) = h1_5 / 720.0
1034 asys(6,5) = - h2_5 / 720.0
1035 asys(6,6) = - n6 / 720.0
1037 bsys(:) = (/ -1.0, -h2, -0.5*h2_2, -h2_3/6.0, -h2_4/24.0, -h2_5/120.0 /)
1039 call solve_linear_system( asys, bsys, csys, 6 )
1051 tri_b(n) = a * u(n-3) + b * u(n-2) + c * u(n-1) + d * u(n)
1054 g = max( hneglect, hminfrac*sum(h(n-5:n)) )
1057 x(i) = x(i-1) + max( g, h(n-7+i) )
1063 asys(i,j) = ( (x(i+1)**j) - (x(i)**j) ) / j
1066 bsys(i) = u(n-6+i) * max( g, h(n-6+i) )
1070 call solve_linear_system( asys, bsys, csys, 6 )
1075 tri_b(n+1) = evaluation_polynomial( csys, 6, x(7) )
1078 call solve_tridiagonal_system( tri_l, tri_d, tri_u, tri_b, tri_x, n+1 )
1081 edge_val(i,1) = tri_x(i)
1082 edge_val(i-1,2) = tri_x(i)
1084 edge_val(1,1) = tri_x(1)
1085 edge_val(n,2) = tri_x(n+1)
1087 end subroutine edge_values_implicit_h6