-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Classic Newton implementation attempt. Not functional yet.
- Loading branch information
Showing
8 changed files
with
628 additions
and
45 deletions.
There are no files selected for viewing
This file contains 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,64 @@ | ||
module LightKrylov_AbstractSystems | ||
use LightKrylov_AbstractVectors | ||
use LightKrylov_AbstractLinops | ||
implicit none | ||
private | ||
|
||
character*128, parameter :: this_module = 'LightKrylov_AbstractSystems' | ||
|
||
!> General abstract type for general systems. | ||
type, abstract, public :: abstract_dynamical_system | ||
end type abstract_dynamical_system | ||
|
||
!----------------------------------------------------------- | ||
!----- ABSTRACT GENERAL SYSTEM TYPE DEFINITION ----- | ||
!----------------------------------------------------------- | ||
|
||
!> Abstract Jacobian linop. | ||
type, abstract, extends(abstract_linop_rdp), public :: abstract_jacobian_linop_rdp | ||
class(abstract_vector_rdp), allocatable :: X | ||
contains | ||
private | ||
procedure(abstract_jac_matvec_rdp), pass(self), deferred, public :: matvec | ||
procedure(abstract_jac_matvec_rdp), pass(self), deferred, public :: rmatvec | ||
end type | ||
|
||
abstract interface | ||
subroutine abstract_jac_matvec_rdp(self, vec_in, vec_out) | ||
!! Interface for the matrix-vector product. | ||
use lightkrylov_AbstractVectors | ||
import abstract_jacobian_linop_rdp | ||
class(abstract_jacobian_linop_rdp) , intent(in) :: self | ||
!! Linear operator \(\mathbf{A}\). | ||
class(abstract_vector_rdp), intent(in) :: vec_in | ||
!! Vector to be multiplied by \(\mathbf{A}\). | ||
class(abstract_vector_rdp), intent(out) :: vec_out | ||
!! Result of the matrix-vector product. | ||
end subroutine abstract_jac_matvec_rdp | ||
end interface | ||
|
||
!> Abstract continuous system. | ||
type, abstract, extends(abstract_dynamical_system), public :: abstract_system_rdp | ||
class(abstract_jacobian_linop_rdp), allocatable :: jacobian | ||
!! System Jacobian \( \left. \frac{\partial \mathbf{F}}{\partial \mathbf{X}} \right|_{X^*} \). | ||
contains | ||
private | ||
procedure(abstract_eval_rdp), pass(self), deferred, public :: eval | ||
!! Procedure to evaluate the system response \( \mathbf{Y} = \mathbf{F}(\mathbf{X}) \). | ||
end type | ||
|
||
abstract interface | ||
subroutine abstract_eval_rdp(self, vec_in, vec_out) | ||
!! Interface for the evaluation of the system response. | ||
use LightKrylov_AbstractVectors | ||
import abstract_system_rdp | ||
class(abstract_system_rdp), intent(in) :: self | ||
!! System | ||
class(abstract_vector_rdp), intent(in) :: vec_in | ||
!! Base state | ||
class(abstract_vector_rdp), intent(out) :: vec_out | ||
!! System response | ||
end subroutine abstract_eval_rdp | ||
end interface | ||
|
||
end module LightKrylov_AbstractSystems |
This file contains 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 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 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,91 @@ | ||
module LightKrylov_NewtonKrylov | ||
use stdlib_optval, only: optval | ||
use LightKrylov_Constants | ||
use LightKrylov_Logger | ||
use LightKrylov_AbstractVectors | ||
use LightKrylov_AbstractLinops | ||
use LightKrylov_AbstractSystems | ||
use LightKrylov_IterativeSolvers | ||
|
||
implicit none | ||
private | ||
|
||
character*128, parameter :: this_module = 'LightKrylov_NewtonKrylov' | ||
|
||
public :: newton | ||
|
||
interface newton | ||
module procedure newton_classic_rdp | ||
end interface | ||
|
||
contains | ||
|
||
subroutine newton_classic_rdp(sys, X0, tol, verb, info) | ||
!! Classic no-frills implementation of the Newton-Krylov root-finding algorithm | ||
class(abstract_system_rdp), intent(inout) :: sys | ||
!! Dynamical system for which we wish to compute a fixed point | ||
class(abstract_vector_rdp), intent(inout) :: X0 | ||
!! Initial guess for the fixed point, will be overwritten with solution | ||
real(dp), intent(in) :: tol | ||
!! Solver tolerance | ||
logical, optional, intent(in) :: verb | ||
!! verbosity toggle | ||
integer, intent(out) :: info | ||
!! Information flag | ||
|
||
!-------------------------------------- | ||
!----- Internal variables ----- | ||
!-------------------------------------- | ||
! residual vector | ||
class(abstract_vector_rdp), allocatable :: residual, X, dX | ||
real(dp) :: rnorm | ||
logical :: converged, verb_ | ||
integer :: i, maxiter | ||
|
||
! Optional parameters | ||
verb_ = optval(verb, .false.) | ||
|
||
! Initialisation | ||
maxiter = 100 | ||
converged = .false. | ||
allocate(residual, source=X0); call residual%zero() | ||
allocate(dX, source=X0); call dX%zero() | ||
allocate(X, source=X0); | ||
|
||
! Newton iteration | ||
newton: do i = 1, maxiter | ||
|
||
call sys%eval(X0, X) | ||
rnorm = X%norm() | ||
if (verb) write(*,*) "Iteration", i, ": Residual norm = ", rnorm | ||
|
||
! Check for convergence. | ||
if (rnorm < tol) then | ||
if (verb) write(*,*) "Convergence achieved." | ||
converged = .true. | ||
exit newton | ||
end if | ||
|
||
! Define the Jacobian | ||
call sys%jacobian%X%axpby(zero_rdp, X, one_rdp) | ||
|
||
! Solve the linear system using GMRES. | ||
call residual%chsgn() | ||
call gmres(sys%jacobian, residual, dX, info) | ||
call check_info(info, 'gmres', module=this_module, procedure='newton_classic_rdp') | ||
|
||
! Update the solution and overwrite X0 | ||
call X0%axpby(zero_rdp, X, one_rdp) | ||
call X0%add(dX) | ||
|
||
enddo newton | ||
|
||
if (.not.converged) then | ||
if (verb) write(*,*) 'Newton iteration did not converge within', maxiter, 'steps.' | ||
info = -1 | ||
endif | ||
|
||
return | ||
end subroutine newton_classic_rdp | ||
|
||
end module LightKrylov_NewtonKrylov |
This file contains 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.