-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsemiimplicit_module.f90
47 lines (34 loc) · 1.21 KB
/
semiimplicit_module.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
module semiimplicit_module
use kind_module, only: i4b, dp
use earth_module, only: earth_radius
implicit none
private
public :: semiimplicit_inverse
contains
subroutine semiimplicit_inverse(bmatrix, beta, dt, invamatrix)
implicit none
real(kind=dp), dimension(:,:), intent(in) :: bmatrix
real(kind=dp), intent(in) :: beta, dt
real(kind=dp), dimension(:,:,0:), intent(inout) :: invamatrix
integer(kind=i4b) :: nz, ntrunc, n, k
real(kind=dp) :: f
! lapack related variables
integer(kind=i4b) :: info
integer(kind=i4b), dimension(size(bmatrix,1)) :: ipiv
real(kind=dp), dimension(1) :: work_dummy
real(kind=dp), dimension(:), allocatable :: work
nz = size(bmatrix,1)
ntrunc = size(invamatrix,3)-1
invamatrix(:,:,:) = 0.0_dp
do k=1, nz
invamatrix(k,k,:) = 1.0_dp
end do
call dgetri(nz,invamatrix,nz,ipiv,work_dummy,-1,info)
allocate(work(int(work_dummy(1))))
f = (1.0_dp/earth_radius*beta*dt)**2 ! 1/a^2 (beta dt)^2
do n=0, ntrunc
invamatrix(:,:,n) = invamatrix(:,:,n) + n*(n+1)*f*bmatrix(:,:)
call dgetri(nz,invamatrix,nz,ipiv,work,size(work),info)
end do
end subroutine semiimplicit_inverse
end module semiimplicit_module