-
Notifications
You must be signed in to change notification settings - Fork 191
feat: [linalg] add iterative solvers #994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jalvesz
wants to merge
49
commits into
fortran-lang:master
Choose a base branch
from
jalvesz:iterative
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 35 commits
Commits
Show all changes
49 commits
Select commit
Hold shift + click to select a range
716b3c5
start iterative solvers
jalvesz 9ed419f
simplify workspace
jalvesz 9106676
add pccg solver and example
jalvesz 297a18d
Merge branch 'fortran-lang:master' into iterative
jalvesz 9eccdd8
Merge branch 'fortran-lang:master' into iterative
jalvesz a93f6b7
Merge branch 'fortran-lang:master' into iterative
jalvesz 16e5cd7
Merge branch 'fortran-lang:master' into iterative
jalvesz e551a5d
complete cg with dirichlet flag, add example, fix di filter
jalvesz 9309c5c
Merge branch 'fortran-lang:master' into iterative
jalvesz 19167d5
add other sparse matrices
jalvesz 9324971
add example for custom solver extending the generic interface
jalvesz 71c2630
Merge branch 'iterative' of https://github.com/jalvesz/stdlib into it…
jalvesz 85a70ba
small simplifications for working data
jalvesz 84f4bc9
make default inner_product point to a default dot_product add enum fo…
jalvesz 3ec23a4
make preconditionner a linop
jalvesz bfafaa5
use facility size
jalvesz 0b01dbd
Add a customizable logger facility, change linop matvec to apply
jalvesz 07b97ce
change internal procedure names for custom example
jalvesz 379cd81
refactor to remove hard dependency on dirichlet BCs
jalvesz 5e15a33
add forward/backward solvers for preconditionning
jalvesz 8c2aa90
fix solve forward/backward
jalvesz e7bb7ce
Merge branch 'fortran-lang:master' into iterative
jalvesz 517291a
fix colum index
jalvesz 2c2196a
Merge branch 'iterative' of https://github.com/jalvesz/stdlib into it…
jalvesz 367987a
add preconditionners
jalvesz 05c076b
fix cmake
jalvesz f027017
add factorizations
jalvesz 7fd2586
backward solve to use Lt marix
jalvesz c596ac0
start unit testing
jalvesz acefaaf
review csr factorization
jalvesz f413cbf
change name generic for kernel
jalvesz 5cb2ad7
Merge branch 'fortran-lang:master' into iterative
jalvesz ea7d35e
shorten factorization procedures names
jalvesz 8068f2d
Merge branch 'fortran-lang:master' into iterative
jalvesz eeddf7c
change precond ldl name
jalvesz b239028
rename to pcg
jalvesz 724289f
Merge branch 'iterative' of https://github.com/jalvesz/stdlib into it…
jalvesz 79dbbbe
Merge branch 'fortran-lang:master' into iterative
jalvesz 463259b
start working on the documentation
jalvesz 6627f4c
clean docstrings
jalvesz fe331f9
add cg and pcg tests
jalvesz 9e5d000
Update example/linalg/example_solve_cg.f90
jalvesz 0f9732e
add _type suffix
jalvesz 177e545
reduce PR scope
jalvesz e68ce8e
rename wksp size constants
jalvesz 1bc601c
rename constant
jalvesz 64f83f8
Merge branch 'fortran-lang:master' into iterative
jalvesz a4d53e1
Merge branch 'fortran-lang:master' into iterative
jalvesz 076a05d
Merge branch 'fortran-lang:master' into iterative
jalvesz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
program example_solve_pccg | ||
use stdlib_kinds, only: dp | ||
use stdlib_linalg_iterative_solvers, only: solve_cg | ||
|
||
real(dp) :: matrix(2,2) | ||
real(dp) :: x(2), load(2) | ||
|
||
matrix = reshape( [4, 1,& | ||
1, 3] , [2,2]) | ||
|
||
x = dble( [2,1] ) !> initial guess | ||
load = dble( [1,2] ) !> load vector | ||
|
||
call solve_cg(matrix, load, x, restart=.false.) | ||
print *, x !> solution: [0.0909, 0.6364] | ||
|
||
end program |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
module custom_solver | ||
use stdlib_kinds, only: dp | ||
use stdlib_sparse | ||
use stdlib_linalg_iterative_solvers, only: linop_dp, & | ||
solver_workspace_dp, & | ||
solve_pccg_kernel, & | ||
size_wksp_pccg | ||
implicit none | ||
contains | ||
subroutine solve_pccg_custom(A,b,x,di,tol,maxiter,restart,workspace) | ||
type(CSR_dp_type), intent(in) :: A | ||
real(dp), intent(in) :: b(:) | ||
real(dp), intent(inout) :: x(:) | ||
real(dp), intent(in), optional :: tol | ||
logical(1), intent(in), optional, target :: di(:) | ||
integer, intent(in), optional :: maxiter | ||
logical, intent(in), optional :: restart | ||
type(solver_workspace_dp), optional, intent(inout), target :: workspace | ||
!------------------------- | ||
type(linop_dp) :: op | ||
type(linop_dp) :: M | ||
type(solver_workspace_dp), pointer :: workspace_ | ||
integer :: n, maxiter_ | ||
real(dp) :: tol_ | ||
logical :: restart_ | ||
logical(1), pointer :: di_(:) | ||
real(dp), allocatable :: diagonal(:) | ||
real(dp) :: norm_sq0 | ||
!------------------------- | ||
n = size(b) | ||
maxiter_ = n; if(present(maxiter)) maxiter_ = maxiter | ||
restart_ = .true.; if(present(restart)) restart_ = restart | ||
tol_ = 1.e-4_dp; if(present(tol)) tol_ = tol | ||
norm_sq0 = 0.d0 | ||
!------------------------- | ||
! internal memory setup | ||
op%apply => my_apply | ||
op%inner_product => my_dot | ||
M%apply => my_jacobi_preconditionner | ||
if(present(di))then | ||
di_ => di | ||
else | ||
allocate(di_(n),source=.false._1) | ||
end if | ||
|
||
if(present(workspace)) then | ||
workspace_ => workspace | ||
else | ||
allocate( workspace_ ) | ||
end if | ||
if(.not.allocated(workspace_%tmp)) allocate( workspace_%tmp(n,size_wksp_pccg) , source = 0.d0 ) | ||
workspace_%callback => my_logger | ||
!------------------------- | ||
! Jacobi preconditionner factorization | ||
call diag(A,diagonal) | ||
where(abs(diagonal)>epsilon(0.d0)) diagonal = 1._dp/diagonal | ||
!------------------------- | ||
! main call to the solver | ||
call solve_pccg_kernel(op,M,b,x,tol_,maxiter_,workspace_) | ||
|
||
!------------------------- | ||
! internal memory cleanup | ||
if(.not.present(di)) deallocate(di_) | ||
di_ => null() | ||
|
||
if(.not.present(workspace)) then | ||
deallocate( workspace_%tmp ) | ||
deallocate( workspace_ ) | ||
end if | ||
workspace_ => null() | ||
contains | ||
|
||
subroutine my_apply(x,y,alpha,beta) | ||
real(dp), intent(in) :: x(:) | ||
real(dp), intent(inout) :: y(:) | ||
real(dp), intent(in) :: alpha | ||
real(dp), intent(in) :: beta | ||
call spmv( A , x, y , alpha, beta ) | ||
y = merge( 0._dp, y, di_ ) | ||
end subroutine | ||
subroutine my_jacobi_preconditionner(x,y,alpha,beta) | ||
real(dp), intent(in) :: x(:) | ||
real(dp), intent(inout) :: y(:) | ||
real(dp), intent(in) :: alpha | ||
real(dp), intent(in) :: beta | ||
y = merge( 0._dp, diagonal * x , di_ ) | ||
end subroutine | ||
pure real(dp) function my_dot(x,y) result(r) | ||
real(dp), intent(in) :: x(:) | ||
real(dp), intent(in) :: y(:) | ||
r = dot_product(x,y) | ||
end function | ||
subroutine my_logger(x,norm_sq,iter) | ||
real(dp), intent(in) :: x(:) | ||
real(dp), intent(in) :: norm_sq | ||
integer, intent(in) :: iter | ||
if(iter == 0) norm_sq0 = norm_sq | ||
print *, "Iteration: ", iter, " Residual: ", sqrt(norm_sq), " Relative: ", sqrt(norm_sq)/sqrt(norm_sq0) | ||
end subroutine | ||
end subroutine | ||
|
||
end module custom_solver | ||
|
||
|
||
program example_solve_custom | ||
use custom_solver | ||
implicit none | ||
|
||
type(CSR_dp_type) :: laplacian_csr | ||
type(COO_dp_type) :: COO | ||
real(dp) :: laplacian(5,5) | ||
real(dp) :: x(5), load(5) | ||
logical(1) :: dirichlet(5) | ||
|
||
laplacian = reshape( [1, -1, 0, 0, 0,& | ||
-1, 2, -1, 0, 0,& | ||
0, -1, 2, -1, 0,& | ||
0, 0, -1, 2, -1,& | ||
0, 0, 0, -1, 1] , [5,5]) | ||
call dense2coo(laplacian,COO) | ||
call coo2csr(COO,laplacian_csr) | ||
|
||
x = 0._dp | ||
load = dble( [0,0,5,0,0] ) | ||
|
||
dirichlet = .false._1 | ||
dirichlet([1,5]) = .true._1 | ||
|
||
call solve_pccg_custom(laplacian_csr, load, x, tol=1.d-6, di=dirichlet) | ||
print *, x !> solution: [0.0, 2.5, 5.0, 2.5, 0.0] | ||
|
||
end program example_solve_custom |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
program example_solve_pccg | ||
use stdlib_kinds, only: dp | ||
use stdlib_sparse | ||
use stdlib_linalg_iterative_solvers, only: solve_pccg | ||
|
||
type(CSR_dp_type) :: laplacian_csr | ||
type(COO_dp_type) :: COO | ||
real(dp) :: laplacian(5,5) | ||
real(dp) :: x(5), load(5) | ||
logical(1) :: dirichlet(5) | ||
|
||
laplacian = reshape( [1, -1, 0, 0, 0,& | ||
-1, 2, -1, 0, 0,& | ||
0, -1, 2, -1, 0,& | ||
0, 0, -1, 2, -1,& | ||
0, 0, 0, -1, 1] , [5,5]) | ||
call dense2coo(laplacian,COO) | ||
call coo2csr(COO,laplacian_csr) | ||
|
||
x = 0._dp | ||
load = dble( [0,0,5,0,0] ) | ||
|
||
dirichlet = .false._1 | ||
dirichlet([1,5]) = .true._1 | ||
|
||
call solve_pccg(laplacian, load, x, tol=1.d-6, di=dirichlet) | ||
print *, x !> solution: [0.0, 2.5, 5.0, 2.5, 0.0] | ||
x = 0._dp | ||
|
||
call solve_pccg(laplacian_csr, load, x, tol=1.d-6, di=dirichlet) | ||
print *, x !> solution: [0.0, 2.5, 5.0, 2.5, 0.0] | ||
end program |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.