source: trunk/LMDZ.COMMON/libf/evolution/derivs.f90 @ 3470

Last change on this file since 3470 was 3470, checked in by evos, 4 weeks ago

we added the option to use NS dynamical subsurface ice in the model to more realisticly calculate the amount of ice in the subsurface and therfore the subsurface thermal inertia

File size: 2.9 KB
Line 
1
2subroutine deriv1(z,nz,y,y0,yNp1,yp)
3  ! first derivative of a function y(z) on irregular grid
4  ! upper b.c.: y(0)=y0
5  ! lower b.c.: yp =0
6  implicit none
7  integer, intent(IN) :: nz
8  real(8), intent(IN) :: z(nz),y(nz),y0,yNp1
9  real(8), intent(OUT) :: yp(nz)
10  integer j
11  real(8) hm,hp,c1,c2,c3
12
13  hp = z(2)-z(1)
14  !hm = z(1)
15  c1 = z(1)/(hp*z(2))
16  c2 = 1/z(1) - 1/(z(2)-z(1))
17  c3 = -hp/(z(1)*z(2))
18  yp(1) = c1*y(2) + c2*y(1) + c3*y0
19  do j=2,nz-1
20     hp = z(j+1)-z(j)
21     hm = z(j)-z(j-1)
22     c1 = +hm/(hp*(z(j+1)-z(j-1)))
23     c2 = 1/hm - 1/hp
24     c3 = -hp/(hm*(z(j+1)-z(j-1)))
25     yp(j) = c1*y(j+1) + c2*y(j) + c3*y(j-1)
26  enddo
27  yp(nz) = (yNp1 - y(nz-1))/(2.*(z(nz)-z(nz-1)))
28end subroutine deriv1
29
30
31
32subroutine deriv2_full(z,nz,a,b,a0,b0,bNp1,yp2)
33  ! second derivative (a*b_z)_z on irregular grid
34  ! upper b.c.: a(0)=a0, b(0)=b0
35  ! 2nd order, without cross-terms
36  implicit none
37  integer, intent(IN) :: nz
38  real(8), intent(IN) :: z(nz),a(nz),b(nz),a0,b0,bNp1
39  real(8), intent(OUT) :: yp2(nz)
40  integer j
41  real(8) hm,hp,c1,c2,c3
42 
43  c1 = 1./(z(1)*z(2))
44  c2 = 1./((z(2)-z(1))*z(1))
45  c3 = 1./((z(2)-z(1))*z(2))
46  yp2(1) = -c2*a(1)*b(1) &   
47       &  -c1*a0*b(1) + c1*(a(1)+a0)*b0 &
48       &  -c3*a(2)*b(1) + c3*(a(1)+a(2))*b(2)
49  do j=2,nz-1
50     hp = z(j+1)-z(j)
51     hm = z(j)-z(j-1)
52     c1 = 1./(hm*(z(j+1)-z(j-1)))
53     c2 = 1./(hp*hm)
54     c3 = 1./(hp*(z(j+1)-z(j-1)))
55     yp2(j) = -c2*a(j)*b(j) &   
56          &  -c1*a(j-1)*b(j) + c1*(a(j)+a(j-1))*b(j-1) &
57          &  -c3*a(j+1)*b(j) + c3*(a(j)+a(j+1))*b(j+1)
58  enddo
59
60  ! lower bc: b_z = 0
61  !yp(nz)= 2.*a(nz)*(b(nz-1)-b(nz))/(z(nz)-z(nz-1))**2
62  !more general lower bc
63  yp2(nz) = a(nz)*(bNp1 - 2*b(nz) + b(nz-1))/(z(nz)-z(nz-1))**2
64end subroutine deriv2_full
65
66
67
68subroutine deriv2_simple(z,nz,y,y0,yNp1,yp2)
69  ! second derivative y_zz on irregular grid
70  ! boundary conditions: y(0)=y0, y(nz+1)=yNp1
71  implicit none
72  integer, intent(IN) :: nz
73  real(8), intent(IN) :: z(nz),y(nz),y0,yNp1
74  real(8), intent(OUT) :: yp2(nz)
75  integer j
76  real(8) hm,hp,c1,c2,c3
77
78  c1 = +2./((z(2)-z(1))*z(2))
79  c2 = -2./((z(2)-z(1))*z(1))
80  c3 = +2./(z(1)*z(2))
81  yp2(1) = c1*y(2) + c2*y(1) + c3*y0
82
83  do j=2,nz-1
84     hp = z(j+1)-z(j)
85     hm = z(j)-z(j-1)
86     c1 = +2./(hp*(z(j+1)-z(j-1)))
87     c2 = -2./(hp*hm)
88     c3 = +2./(hm*(z(j+1)-z(j-1)))
89     yp2(j) = c1*y(j+1) + c2*y(j) + c3*y(j-1)
90  enddo
91
92  yp2(nz) = (yNp1 - 2*y(nz) + y(nz-1))/(z(nz)-z(nz-1))**2
93end subroutine deriv2_simple
94
95
96
97real(8) function deriv1_onesided(j,z,nz,y)
98  ! first derivative of function y(z) at z(j)
99  ! one-sided derivative on irregular grid
100  implicit none
101  integer, intent(IN) :: nz,j
102  real(8), intent(IN) :: z(nz),y(nz)
103  real(8) h1,h2,c1,c2,c3
104  if (j<1 .or. j>nz-2) then
105     deriv1_onesided = -9999.
106  else
107     h1 = z(j+1)-z(j)
108     h2 = z(j+2)-z(j+1)
109     c1 = -(2*h1+h2)/(h1*(h1+h2))
110     c2 =  (h1+h2)/(h1*h2)
111     c3 = -h1/(h2*(h1+h2))
112     deriv1_onesided = c1*y(j) + c2*y(j+1) + c3*y(j+2)
113  endif
114end function deriv1_onesided
115
Note: See TracBrowser for help on using the repository browser.