10#include "scaleFElib.h"
33 module procedure linalgebra_solvelineq_b1d
34 module procedure linalgebra_solvelineq_b2d
68 real(rp),
intent(in) :: a(:,:)
69 real(rp) :: ainv(size(a,1),size(a,2))
71 real(rp) :: work(size(a,1))
72 integer :: ipiv(size(a,1))
80 call dgetrf(n, n, ainv, n, ipiv, info)
82 log_error(
"linalgebra_inv",*)
"Matrix is singular"
86 call dgetri(n, ainv, n, ipiv, work, n, info)
88 log_error(
"linalgebra_inv",*)
"Matrix inversion is failed"
96 subroutine linalgebra_solvelineq_b1d(A, b, x)
98 real(RP),
intent(in) :: A(:,:)
99 real(RP),
intent(in) :: b(:)
100 real(RP),
intent(out) :: x(size(b))
102 real(RP) :: A_lu(size(A,1),size(A,2))
103 integer :: ipiv(size(A,1))
111 call dgetrf(n, n, a_lu, n, ipiv, info)
113 log_error(
"linalgebra_SolveLinEq",*)
"Matrix is singular"
118 call dgetrs(
'N', n, 1, a_lu, n, ipiv, x, n, info)
120 log_error(
"linalgebra_SolveLinEq",*)
"Matrix inversion is failed"
125 end subroutine linalgebra_solvelineq_b1d
128 subroutine linalgebra_solvelineq_b2d(A, b, x)
130 real(RP),
intent(in) :: A(:,:)
131 real(RP),
intent(in) :: b(:,:)
132 real(RP),
intent(out) :: x(size(b,1),size(b,2))
134 real(RP) :: A_lu(size(A,1),size(A,2))
135 integer :: ipiv(size(A,1))
143 call dgetrf(n, n, a_lu, n, ipiv, info)
145 log_error(
"linalgebra_SolveLinEq",*)
"Matrix is singular"
150 call dgetrs(
'N', n,
size(b,2), a_lu, n, ipiv, x, n, info)
152 log_error(
"linalgebra_SolveLinEq",*)
"Matrix inversion is failed"
157 end subroutine linalgebra_solvelineq_b2d
162 real(rp),
intent(inout) :: a_lu(:,:)
163 integer,
intent(out) :: ipiv(size(a_lu,1))
171 call dgetrf(n, n, a_lu, n, ipiv, info)
173 log_error(
"linalgebra_LU",*)
"Matrix is singular"
186 real(rp),
intent(in) :: b(:)
187 real(rp),
intent(inout) :: x(:)
188 integer,
intent(in) :: m
189 integer,
intent(in) ::restart_num
190 real(rp),
intent(in) :: conv_crit
192 real(rp) :: x0(size(x))
193 real(rp) :: w(size(x))
194 real(rp) :: v(size(x),m+1)
195 real(rp) :: z(size(x),m+1)
196 real(rp) :: av(size(x))
197 real(rp) :: g(size(x)+1)
198 real(rp) :: r0_l2, r0_l2_new
201 real(rp) :: c(m), s(m)
203 real(rp) :: tmp, tmp1, tmp2
211 call precondstep_ilu0_constructmat(a, m_pc)
214 do restart_i=1, restart_num
216 if (restart_i == 1)
then
219 r0_l2 = sqrt(sum(v(:,1)**2))
221 v(:,1) = v(:,1)/r0_l2
226 call precondstep_ilu0_solve(m_pc, v(:,j), z(:,j))
231 h(i,j) = sum(w*v(:,i))
232 w(:) = w - h(i,j)*v(:,i)
234 h(j+1,j) = sqrt(sum(w**2))
235 v(:,j+1) = w(:)/h(j+1,j)
239 tmp1 = c(i)*r(i,j) + s(i)*h(i+1,j)
240 tmp2 = -s(i)*r(i,j) + c(i)*h(i+1,j)
245 tmp = sqrt(r(j,j)**2 + h(j+1,j)**2)
251 r(j,j) = c(j)*r(j,j) + s(j)*h(j+1,j)
256 y(i) = (g(i) - sum(r(i,i+1:m)*y(i+1:m)))/r(i,i)
259 x(:) = x + matmul(z(:,1:m),y)
266 r0_l2_new = sqrt(sum(v(:,1)**2))
269 if (r0_l2_new < conv_crit)
exit
276 subroutine precondstep_ptjacobi(A, b, x)
278 type(sparsemat),
intent(in) :: a
279 real(rp),
intent(in) :: b(:)
280 real(rp),
intent(out) :: x(size(b))
286 x(n) = b(n) / a%GetVal(n, n)
290 end subroutine precondstep_ptjacobi
292 subroutine precondstep_ilu0_constructmat(A, M)
293 use scale_const,
only: &
297 type(sparsemat),
intent(in) :: a
298 type(sparsemat),
intent(inout) :: m
300 integer :: i, j, k, n
301 real(rp) :: mij, m_ik, m_kk
311 if ( abs(m_ik) < eps .and. abs(m_kk) < eps )
then
313 call m%ReplaceVal( i, k, m_ik )
317 if ( abs(mij) < eps )
then
318 call m%ReplaceVal( i, j, mij - m%GetVal(i,k) * m%GetVal(k,j) )
326 end subroutine precondstep_ilu0_constructmat
328 subroutine precondstep_ilu0_solve(M, b, x)
334 real(rp),
intent(in) :: b(:)
335 real(rp),
intent(out) :: x(size(b))
345 log_error(
"linalgebra_PreCondStep_ILU0_solve",*)
"The strorge type of specified sparse matrix is not supported. Check!"
357 if (m%colIdx(j) <= i-1) &
358 x(i) = x(i) - m%val(j)*x(m%colIdx(j))
362 x(n) = x(n) / m%GetVal(n,n)
367 if (m%colIdx(j) >= i+1) &
368 x(i) = x(i) - m%val(j)*x(m%colIdx(j))
370 x(i) = x(i)/m%GetVal(i,i)
374 end subroutine precondstep_ilu0_solve
module common / Linear algebra
real(rp) function, dimension(size(a, 1), size(a, 2)), public linalgebra_inv(a)
subroutine, public linalgebra_solvelineq_gmres(a, b, x, m, restart_num, conv_crit)
subroutine, public linalgebra_lu(a_lu, ipiv)
module common / sparsemat
integer, parameter, public sparsemat_storage_typeid_csr