source: trunk/LMDZ.COMMON/libf/evolution/math_mod.F90 @ 2961

Last change on this file since 2961 was 2961, checked in by llange, 19 months ago

PEM

  • Move math functions (findroot, deriv, etc) in a specific module
  • Ice table is no longer infinite, the bottom of the ice table (zend) is set such at d(rho_vap) dz (zend) = 0. Future commit will transfer the loss of ice table to perenial glaciers

LL

File size: 4.6 KB
Line 
1module math_mod
2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3!!!
4!!! Purpose: The module contains all the mathematical subroutine used in the PEM
5!!!           
6!!! Author: Adapted from Schorgofer MSIM (N.S, Icarus 2010), impletented here by LL
7!!!
8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9  implicit none
10  contains
11
12
13subroutine deriv1(z,nz,y,y0,ybot,dzY)
14!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
15!!!
16!!! Purpose: Compute the first derivative of a function y(z) on an irregular grid
17!!!           
18!!! Author: From N.S (N.S, Icarus 2010), impletented here by LL
19!!!
20!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21        implicit none
22
23! first derivative of a function y(z) on irregular grid
24! upper boundary conditions: y(0)=y0
25! lower boundary condition.: yp = ybottom
26  integer, intent(IN) :: nz ! number of layer
27  real, intent(IN) :: z(nz) ! depth layer
28  real, intent(IN) :: y(nz) ! function which needs to be derived
29  real, intent(IN) :: y0,ybot ! boundary conditions
30  real, intent(OUT) :: dzY(nz) ! derivative of y w.r.t depth
31! local
32  integer :: j
33  real :: hm,hp,c1,c2,c3
34
35  hp = z(2)-z(1)
36  c1 = z(1)/(hp*z(2))
37  c2 = 1/z(1) - 1/(z(2)-z(1))
38  c3 = -hp/(z(1)*z(2))
39  dzY(1) = c1*y(2) + c2*y(1) + c3*y0
40  do j=2,nz-1
41     hp = z(j+1)-z(j)
42     hm = z(j)-z(j-1)
43     c1 = +hm/(hp*(z(j+1)-z(j-1)))
44     c2 = 1/hm - 1/hp
45     c3 = -hp/(hm*(z(j+1)-z(j-1)))
46     dzY(j) = c1*y(j+1) + c2*y(j) + c3*y(j-1)
47  enddo
48  dzY(nz) = (ybot - y(nz-1))/(2.*(z(nz)-z(nz-1)))
49 return
50end subroutine deriv1
51
52
53
54subroutine deriv2_simple(z,nz,y,y0,yNp1,yp2)
55!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
56!!!
57!!! Purpose: Compute the second derivative of a function y(z) on an irregular grid
58!!!           
59!!! Author: N.S (raw copy/paste from MSIM)
60!!!
61!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
62
63  ! second derivative y_zz on irregular grid
64  ! boundary conditions: y(0)=y0, y(nz+1)=yNp1
65  implicit none
66  integer, intent(IN) :: nz
67  real, intent(IN) :: z(nz),y(nz),y0,yNp1
68  real, intent(OUT) :: yp2(nz)
69  integer j
70  real hm,hp,c1,c2,c3
71
72  c1 = +2./((z(2)-z(1))*z(2))
73  c2 = -2./((z(2)-z(1))*z(1))
74  c3 = +2./(z(1)*z(2))
75  yp2(1) = c1*y(2) + c2*y(1) + c3*y0
76
77  do j=2,nz-1
78     hp = z(j+1)-z(j)
79     hm = z(j)-z(j-1)
80     c1 = +2./(hp*(z(j+1)-z(j-1)))
81     c2 = -2./(hp*hm)
82     c3 = +2./(hm*(z(j+1)-z(j-1)))
83     yp2(j) = c1*y(j+1) + c2*y(j) + c3*y(j-1)
84  enddo
85  yp2(nz) = (yNp1 - 2*y(nz) + y(nz-1))/(z(nz)-z(nz-1))**2
86  return
87end subroutine deriv2_simple
88
89
90
91subroutine  deriv1_onesided(j,z,nz,y,dy_zj)
92!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
93!!!
94!!! Purpose:   First derivative of function y(z) at z(j)  one-sided derivative on irregular grid
95!!!           
96!!! Author: N.S (raw copy/paste from MSIM)
97!!!
98!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
99
100  implicit none
101  integer, intent(IN) :: nz,j
102  real, intent(IN) :: z(nz),y(nz)
103  real, intent(out) :: dy_zj
104  real h1,h2,c1,c2,c3
105  if (j<1 .or. j>nz-2) then
106     dy_zj = -1.
107  else
108     h1 = z(j+1)-z(j)
109     h2 = z(j+2)-z(j+1)
110     c1 = -(2*h1+h2)/(h1*(h1+h2))
111     c2 =  (h1+h2)/(h1*h2)
112     c3 = -h1/(h2*(h1+h2))
113     dy_zj = c1*y(j) + c2*y(j+1) + c3*y(j+2)
114  endif
115  return
116end subroutine deriv1_onesided
117
118
119subroutine  colint(y,z,nz,i1,i2,integral)
120!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
121!!!
122!!! Purpose:  Column integrates y on irregular grid
123!!!           
124!!! Author: N.S (raw copy/paste from MSIM)
125!!!
126!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
127 
128  implicit none
129  integer, intent(IN) :: nz, i1, i2
130  real, intent(IN) :: y(nz), z(nz)
131  real,intent(out) :: integral
132  integer i
133  real dz(nz)
134 
135  dz(1) = (z(2)-0.)/2
136  do i=2,nz-1
137     dz(i) = (z(i+1)-z(i-1))/2.
138  enddo
139  dz(nz) = z(nz)-z(nz-1)
140  integral = sum(y(i1:i2)*dz(i1:i2))
141end subroutine colint
142
143
144
145
146
147SUBROUTINE findroot(y1,y2,z1,z2,zr)
148        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
149        !!!
150        !!! Purpose: Compute the root zr, between two values y1 and y2 at depth z1,z2
151        !!!
152        !!! Author: LL
153        !!!
154        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
155
156        implicit none
157        real,intent(in) :: y1,y2 ! difference between surface water density and at depth  [kg/m^3]
158        real,intent(in) :: z1,z2 ! depth [m]
159        real,intent(out) :: zr ! depth at which we have zero
160        zr = (y1*z2 - y2*z1)/(y1-y2)
161        RETURN
162        end subroutine findroot
163
164end module math_mod
Note: See TracBrowser for help on using the repository browser.