Changeset 3553 for trunk/LMDZ.COMMON/libf/evolution/math_mod.F90
- Timestamp:
- Dec 16, 2024, 5:30:48 PM (7 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.COMMON/libf/evolution/math_mod.F90
r3532 r3553 28 28 implicit none 29 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 35 ! local 30 ! Inputs 31 !------- 32 integer, intent(in) :: nz ! number of layer 33 real, dimension(nz), intent(in) :: z ! depth layer 34 real, dimension(nz), intent(in) :: y ! function which needs to be derived 35 real, intent(in) :: y0, ybot ! boundary conditions 36 ! Outputs 37 !-------- 38 real, dimension(nz), intent(out) :: dzY ! derivative of y w.r.t depth 39 ! Local variables 40 !---------------- 36 41 integer :: j 37 42 real :: hm, hp, c1, c2, c3 … … 69 74 implicit none 70 75 71 integer, intent(in) :: nz 72 real, intent(in) :: z(nz), y(nz), y0, yNp1 73 real, intent(out) :: yp2(nz) 76 ! Inputs 77 !------- 78 integer, intent(in) :: nz 79 real, dimension(nz), intent(in) :: z, y 80 real, intent(in) :: y0, yNp1 81 ! Outputs 82 !-------- 83 real, dimension(nz), intent(out) :: yp2 84 ! Local variables 85 !---------------- 74 86 integer :: j 75 87 real :: hm, hp, c1, c2, c3 … … 102 114 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 103 115 104 implicit none 105 106 integer, intent(in) :: nz, j 107 real, intent(in) :: z(nz), y(nz) 116 implicit none 117 118 ! Inputs 119 !------- 120 integer, intent(in) :: nz, j 121 real, dimension(nz), intent(in) :: z, y 122 ! Outputs 123 !-------- 108 124 real, intent(out) :: dy_zj 125 ! Local viariables 126 !----------------- 109 127 real :: h1, h2, c1, c2, c3 110 128 … … 135 153 implicit none 136 154 137 integer, intent(in) :: nz, i1, i2 138 real, intent(in) :: y(nz), z(nz) 155 ! Inputs 156 !------- 157 integer, intent(in) :: nz, i1, i2 158 real, dimension(nz), intent(in) :: y, z 159 ! Outputs 160 !-------- 139 161 real, intent(out) :: integral 140 integer i 141 real dz(nz) 162 ! Local viariables 163 !----------------- 164 integer :: i 165 real, dimension(nz) :: dz 142 166 143 167 dz(1) = (z(2) - 0.)/2 … … 163 187 implicit none 164 188 189 ! Inputs 190 !------- 165 191 real, intent(in) :: y1, y2 ! difference between surface water density and at depth [kg/m^3] 166 192 real, intent(in) :: z1, z2 ! depth [m] 167 real, intent(out) :: zr ! depth at which we have zero 193 ! Outputs 194 !-------- 195 real, intent(out) :: zr ! depth at which we have zero 168 196 169 197 zr = (y1*z2 - y2*z1)/(y1 - y2) … … 171 199 END SUBROUTINE findroot 172 200 201 !======================================================================= 202 203 SUBROUTINE solve_tridiag(a,b,c,d,n,x,error) 204 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 205 !!! 206 !!! Purpose: Solve a tridiagonal system Ax = d using the Thomas' algorithm 207 !!! a: sub-diagonal 208 !!! b: main diagonal 209 !!! c: super-diagonal 210 !!! d: right-hand side 211 !!! x: solution 212 !!! 213 !!! Author: JBC 214 !!! 215 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 216 217 implicit none 218 219 ! Inputs 220 !------- 221 integer, intent(in) :: n 222 real, dimension(n), intent(in) :: b, d 223 real, dimension(n - 1), intent(in) :: a, c 224 ! Outputs 225 !-------- 226 real, dimension(n), intent(out) :: x 227 integer, intent(out) :: error 228 ! Local viariables 229 !----------------- 230 integer :: i 231 real :: m 232 real, dimension(n) :: cp, dp 233 234 ! Check stability: diagonally dominant condition 235 error = 0 236 if (abs(b(1)) < abs(c(1))) then 237 error = 1 238 return 239 endif 240 do i = 2,n - 1 241 if (abs(b(i)) < abs(a(i - 1)) + abs(c(i))) then 242 error = 1 243 return 244 endif 245 enddo 246 if (abs(b(n)) < abs(a(n - 1))) then 247 error = 1 248 return 249 endif 250 251 ! Initialization 252 cp(1) = c(1)/b(1) 253 dp(1) = d(1)/b(1) 254 255 ! Forward sweep 256 do i = 2,n - 1 257 m = b(i) - a(i - 1)*cp(i - 1) 258 cp(i) = c(i)/m 259 dp(i) = (d(i) - a(i - 1)*dp(i - 1))/m 260 enddo 261 m = b(n) - a(n - 1)*cp(n - 1) 262 dp(n) = (d(n) - a(n - 1)*dp(n - 1))/m 263 264 ! Backward substitution 265 x(n) = dp(n) 266 do i = n - 1,1,-1 267 x(i) = dp(i) - cp(i)*x(i + 1) 268 enddo 269 270 END SUBROUTINE solve_tridiag 271 272 !======================================================================= 273 274 SUBROUTINE solve_steady_heat(n,z,mz,kappa,mkappa,T_left,q_right,T) 275 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 276 !!! 277 !!! Purpose: Solve 1D steady-state heat equation with space-dependent diffusivity 278 !!! Left boudary condition : prescribed temperature T_left 279 !!! Right boudary condition: prescribed thermal flux q_right 280 !!! 281 !!! z : grid points 282 !!! mz : mid-grid points 283 !!! kappa : thermal diffusivity at grid points 284 !!! mkappa: thermal diffusivity at mid-grid points 285 !!! 286 !!! Author: JBC 287 !!! 288 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 289 290 use abort_pem_mod, only: abort_pem 291 292 implicit none 293 294 ! Inputs 295 !------- 296 integer, intent(in) :: n 297 real, dimension(n), intent(in) :: z, kappa 298 real, dimension(n - 1), intent(in) :: mz, mkappa 299 real, intent(in) :: T_left, q_right 300 ! Outputs 301 !-------- 302 real, dimension(n), intent(out) :: T 303 ! Local viariables 304 !----------------- 305 integer :: i, error 306 real, dimension(n) :: b, d 307 real, dimension(n - 1) :: a, c 308 309 ! Initialization 310 a = 0.; b = 0.; c = 0.; d = 0. 311 312 ! Left boundary condition (Dirichlet: prescribed temperature) 313 b(1) = 1. 314 d(1) = T_left 315 316 ! Internal points 317 do i = 2,n - 1 318 a(i - 1) = -mkappa(i - 1)/((mz(i) - mz(i - 1))*(z(i) - z(i - 1))) 319 c(i) = -mkappa(i)/((mz(i) - mz(i - 1))*(z(i + 1) - z(i))) 320 b(i) = -(a(i - 1) + c(i)) 321 enddo 322 323 ! Right boundary condition (Neumann: prescribed temperature) 324 a(n - 1) = kappa(n - 1)/(z(n) - z(n - 1)) 325 b(n) = -kappa(n)/(z(n) - z(n - 1)) 326 d(n) = q_right 327 328 ! Solve the tridiagonal linear system with the Thomas' algorithm 329 call solve_tridiag(a,b,c,d,n,T,error) 330 if (error /= 0) call abort_pem("solve_steady_heat","Unstable solving!",1) 331 332 END SUBROUTINE solve_steady_heat 333 173 334 end module math_mod
Note: See TracChangeset
for help on using the changeset viewer.