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