Ignore:
Timestamp:
Dec 16, 2024, 5:30:48 PM (7 months ago)
Author:
jbclement
Message:

PEM:
Addition of the shifting of the soil temperature profile to follow the surface evolution due to ice condensation/sublimation + small cleanings/improvements.
JBC

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.COMMON/libf/evolution/math_mod.F90

    r3532 r3553  
    2828implicit none
    2929
    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!-------
     32integer,             intent(in) :: nz       ! number of layer
     33real, dimension(nz), intent(in) :: z        ! depth layer
     34real, dimension(nz), intent(in) :: y        ! function which needs to be derived
     35real,                intent(in) :: y0, ybot ! boundary conditions
     36! Outputs
     37!--------
     38real, dimension(nz), intent(out) :: dzY ! derivative of y w.r.t depth
     39! Local variables
     40!----------------
    3641integer :: j
    3742real    :: hm, hp, c1, c2, c3
     
    6974implicit none
    7075
    71 integer, intent(in) :: nz
    72 real,    intent(in) :: z(nz), y(nz), y0, yNp1
    73 real, intent(out) :: yp2(nz)
     76! Inputs
     77!-------
     78integer,             intent(in) :: nz
     79real, dimension(nz), intent(in) :: z, y
     80real,                intent(in) :: y0, yNp1
     81! Outputs
     82!--------
     83real, dimension(nz), intent(out) :: yp2
     84! Local variables
     85!----------------
    7486integer :: j
    7587real    :: hm, hp, c1, c2, c3
     
    102114!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    103115
    104   implicit none
    105 
    106 integer, intent(in) :: nz, j
    107 real,    intent(in) :: z(nz), y(nz)
     116implicit none
     117
     118! Inputs
     119!-------
     120integer,             intent(in) :: nz, j
     121real, dimension(nz), intent(in) :: z, y
     122! Outputs
     123!--------
    108124real, intent(out) :: dy_zj
     125! Local viariables
     126!-----------------
    109127real :: h1, h2, c1, c2, c3
    110128
     
    135153implicit none
    136154
    137 integer, intent(in) :: nz, i1, i2
    138 real,    intent(in) :: y(nz), z(nz)
     155! Inputs
     156!-------
     157integer,             intent(in) :: nz, i1, i2
     158real, dimension(nz), intent(in) :: y, z
     159! Outputs
     160!--------
    139161real, intent(out) :: integral
    140 integer i
    141 real dz(nz)
     162! Local viariables
     163!-----------------
     164integer             :: i
     165real, dimension(nz) :: dz
    142166
    143167dz(1) = (z(2) - 0.)/2
     
    163187implicit none
    164188
     189! Inputs
     190!-------
    165191real, intent(in) :: y1, y2 ! difference between surface water density and at depth  [kg/m^3]
    166192real, intent(in) :: z1, z2 ! depth [m]
    167 real, intent(out) :: zr    ! depth at which we have zero
     193! Outputs
     194!--------
     195real, intent(out) :: zr ! depth at which we have zero
    168196
    169197zr = (y1*z2 - y2*z1)/(y1 - y2)
     
    171199END SUBROUTINE findroot
    172200
     201!=======================================================================
     202
     203SUBROUTINE 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
     217implicit none
     218
     219! Inputs
     220!-------
     221integer,                intent(in) :: n
     222real, dimension(n),     intent(in) :: b, d
     223real, dimension(n - 1), intent(in) :: a, c
     224! Outputs
     225!--------
     226real, dimension(n), intent(out) :: x
     227integer,            intent(out) :: error
     228! Local viariables
     229!-----------------
     230integer            :: i
     231real               :: m
     232real, dimension(n) :: cp, dp
     233
     234! Check stability: diagonally dominant condition
     235error = 0
     236if (abs(b(1)) < abs(c(1))) then
     237    error = 1
     238    return
     239endif
     240do i = 2,n - 1
     241    if (abs(b(i)) < abs(a(i - 1)) + abs(c(i))) then
     242        error = 1
     243        return
     244    endif
     245enddo
     246if (abs(b(n)) < abs(a(n - 1))) then
     247    error = 1
     248    return
     249endif
     250
     251! Initialization
     252cp(1) = c(1)/b(1)
     253dp(1) = d(1)/b(1)
     254
     255! Forward sweep
     256do 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
     260enddo
     261m = b(n) - a(n - 1)*cp(n - 1)
     262dp(n) = (d(n) - a(n - 1)*dp(n - 1))/m
     263
     264! Backward substitution
     265x(n) = dp(n)
     266do i = n - 1,1,-1
     267    x(i) = dp(i) - cp(i)*x(i + 1)
     268enddo
     269
     270END SUBROUTINE solve_tridiag
     271
     272!=======================================================================
     273
     274SUBROUTINE 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
     290use abort_pem_mod, only: abort_pem
     291
     292implicit none
     293
     294! Inputs
     295!-------
     296integer,                intent(in) :: n
     297real, dimension(n),     intent(in) :: z, kappa
     298real, dimension(n - 1), intent(in) :: mz, mkappa
     299real,                   intent(in) :: T_left, q_right
     300! Outputs
     301!--------
     302real, dimension(n), intent(out) :: T
     303! Local viariables
     304!-----------------
     305integer                :: i, error
     306real, dimension(n)     :: b, d
     307real, dimension(n - 1) :: a, c
     308
     309! Initialization
     310a = 0.; b = 0.; c = 0.; d = 0.
     311
     312! Left boundary condition (Dirichlet: prescribed temperature)
     313b(1) = 1.
     314d(1) = T_left
     315
     316! Internal points
     317do 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))
     321enddo
     322
     323! Right boundary condition (Neumann: prescribed temperature)
     324a(n - 1) = kappa(n - 1)/(z(n) - z(n - 1))
     325b(n) = -kappa(n)/(z(n) - z(n - 1))
     326d(n) = q_right
     327
     328! Solve the tridiagonal linear system with the Thomas' algorithm
     329call solve_tridiag(a,b,c,d,n,T,error)
     330if (error /= 0) call abort_pem("solve_steady_heat","Unstable solving!",1)
     331
     332END SUBROUTINE solve_steady_heat
     333
    173334end module math_mod
Note: See TracChangeset for help on using the changeset viewer.