Skip to content
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

Rank-adaptive Projector-Splitting Integrator for Dynamic Low-Rank Approximation of Lyapunov and Riccati equations #8

Merged
merged 101 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
5548d3b
Updated to fit new LTI type definition
Simkern Apr 5, 2024
0bbb381
Created GL testcase for Lyapunov equations
Simkern Apr 22, 2024
7a61644
Minor change in API, pass A, B, C explicitly, A is in/out
Simkern Apr 23, 2024
3f407e2
DLRA working. Adapted to API change in exptA
Simkern Apr 23, 2024
5024a63
Added tests for controlability and observability Gramians.
Simkern Apr 23, 2024
9e3716d
small fixes
Simkern Apr 24, 2024
947c51c
Small change in API and naming.
Simkern Apr 25, 2024
76fe341
added local folder for tests
Simkern Apr 25, 2024
636ec54
Updated to include balanced transformation test
Simkern Apr 25, 2024
9fc0af7
fixed typo
Simkern Apr 25, 2024
1b8cef5
Moved sqrt and SVD out of the BT function. Bug fixes
Simkern Apr 29, 2024
98919d5
updated example for BT
Simkern Apr 29, 2024
75860cb
Wrapped tests into functions and updated structure
Simkern Apr 30, 2024
b9eaa4a
Added Riccati test and kexpm test
Simkern Apr 30, 2024
efeaa99
added fortime dep
Simkern May 2, 2024
df935b0
made weights equal. n = 128
Simkern May 2, 2024
11fab6d
fixed bug in Obs. Added timing for kexpm test
Simkern May 2, 2024
8af8bab
updated main and added verb flag to R solver
Simkern May 2, 2024
7da2c13
small fix
Simkern May 3, 2024
60efdcc
Updated initialisation with QR factorisation. Added convergence test.
Simkern May 17, 2024
bb52311
Added inhomogeneities to initialisation for Runge-Kutta integration
Simkern May 17, 2024
d47f9ba
Added convergence test
Simkern May 17, 2024
2ddbc8d
Routines needed for Runge-Kutta integration of the Lyapunov equation …
Simkern May 17, 2024
fafdab8
Cosmetics and exported direct_GL and adjoint_GL needed for RK integra…
Simkern May 17, 2024
a0e6ab8
Added residual calculation. Updated RK test
Simkern May 22, 2024
5100a94
Corrected actuator/sensor definition. Added integration weights
Simkern May 22, 2024
6d4d5e5
added integration weights to inner product
Simkern May 22, 2024
01f224b
updated parameters
Simkern May 22, 2024
3df5d5f
fixed typo
Simkern May 23, 2024
4238189
Added CARE residual evaluation
Simkern May 23, 2024
f771f75
Added Q and Rinv matrices for Riccati problem
Simkern May 23, 2024
9885186
updated riccati test with residual computation
Simkern May 23, 2024
58481a4
updates
Simkern May 23, 2024
c1a76e5
merge Riccati into DLRA
Simkern May 23, 2024
877df02
Switch from local LightKrylov to github:LightKrylov/dev
Simkern May 24, 2024
3404162
Begin upgrade to the new LightKrylov API
Simkern May 24, 2024
f0991fe
Point to local LightKylov install until PRs for utility functions are…
Simkern Jun 4, 2024
1a67d83
visual aid for block construct
Simkern Jun 4, 2024
f9a130b
add svals function to extract (only) singular values of a matrix
Simkern Jun 4, 2024
95e6375
fixed issue with DLRA integrators in tests
Simkern Jun 4, 2024
d49132d
Removed sqrtm and zero_basis that have been migrated to LightKrylov
Simkern Jun 5, 2024
a5c58da
small fixed and update examples to new LightKrylov API
Simkern Jun 5, 2024
f1b41b4
refactoring examples
Simkern Jun 5, 2024
729fa8b
pruned use list
Simkern Jun 6, 2024
c66e7ba
update test
Simkern Jun 11, 2024
03f4132
added stop to shorten test
Simkern Jun 11, 2024
565b072
upgraded LyapunovUtils.f90
Simkern Jun 11, 2024
971c11d
upgraded AbstractLTISystems.f90, for now without effective rank
Simkern Jun 11, 2024
ba1999c
upgraded RiccatiUtils.f90
Simkern Jun 11, 2024
3cc0322
upgraded src/Utils.f90
Simkern Jun 11, 2024
e12f001
upgraded example/DLRA_laplacian2D_lti_lyapunov/laplacian2D_lti_lyapun…
Simkern Jun 11, 2024
293e852
upgraded src/LyapunovSolvers.f90
Simkern Jun 11, 2024
594dba7
upgraded src/RiccatiSolvers.f90
Simkern Jun 11, 2024
993e76d
upgraded src/RiccatiSolvers.f90
Simkern Jun 11, 2024
c1bd1bb
updated GL example
Simkern Jun 11, 2024
0331566
updated LTI Lyap example
Simkern Jun 11, 2024
375624e
updated LTI Riccati example
Simkern Jun 11, 2024
22b2ae5
added effective rank to LR_state and updated LyapSolvers accordingly
Simkern Jun 11, 2024
409b8cf
cleanup scratch arrays
Simkern Jun 11, 2024
e09d1d0
added svdvals
Simkern Jun 11, 2024
01b695d
moved integrator choice into main integrator interface. create rank-a…
Simkern Jun 11, 2024
f3be899
added first version of rank-adaptive DLRA integrator
Simkern Jun 11, 2024
0a8dc55
reverted changes in src/Utils.f90, updated examples to new LTI abstra…
Simkern Jun 11, 2024
d77925a
updated to the new version of LightKrylov
Simkern Jun 13, 2024
7983471
Extensions and refactoring
Simkern Jun 13, 2024
cc2c637
Extensions and refactoring
Simkern Jun 13, 2024
bdd290b
Extensions and refactoring
Simkern Jun 13, 2024
2d1fae6
Extensions and refactoring
Simkern Jun 13, 2024
09b4a49
added solution reconstruction
Simkern Jun 13, 2024
be5442b
cosmetic changes
Simkern Jun 13, 2024
5a166d9
add old changes again
Simkern Jun 13, 2024
e5a45e9
upgraded RKlib operators to rdp
Simkern Jun 13, 2024
e443c60
fixed bug
Simkern Jun 13, 2024
95c31b9
typo
Simkern Jun 13, 2024
e648323
cosmetic changes
Simkern Jun 13, 2024
52dacf1
Merge branch 'DLRA_LightKrylov_dev' of github.com:nekStab/LightROM in…
Simkern Jun 13, 2024
158e1d3
fixed typo
Simkern Jun 17, 2024
1750ee7
Cleanup
Simkern Jun 17, 2024
2dfbf49
Major update: added set_initial_rank, compute_splitting_error. Update…
Simkern Jun 17, 2024
c5860e5
fixed type in initalization of LR state
Simkern Jun 17, 2024
64bff6c
fixed typo
Simkern Jun 17, 2024
1dd519f
Added test for rank-adaptive DLRA
Simkern Jun 17, 2024
23fd76e
Added test for rank-adaptive DLRA
Simkern Jun 17, 2024
fc8563f
Conformed to new stdlib with svd+svdvals, added options struct for DL…
Simkern Jun 18, 2024
0b11c4e
add run_tests.sh
Simkern Jun 18, 2024
2e9edcc
small simplification
Simkern Jun 18, 2024
4fc86f9
upgraded riccati. But adding dlra_opts leads to weird compilation iss…
Simkern Jun 18, 2024
8426c3d
Added routine allowing the efficient direct summation or subtraction …
Simkern Jun 20, 2024
b71a679
Updated testing environment, added unit test for project_onto_common_…
Simkern Jun 20, 2024
3b32674
updated rk_init=2 to avoid stdlib svd bug; moved project_onto_common_…
Simkern Jun 20, 2024
9dec27c
updated dlra_opts and exported definitions; added functions for the n…
Simkern Jun 20, 2024
4d5b98b
updated to the dlra_opts workflow
Simkern Jun 20, 2024
5215524
added test for convergence of the rank-adaptive DLRA
Simkern Jun 20, 2024
82e205e
added subroutine to compute increment norm; reset rk_init after stdli…
Simkern Jun 20, 2024
b558ad1
Updated documentation, renamed functions for clarity.
Simkern Jun 20, 2024
4207ee1
poit to LightKrylov.git
Simkern Jun 24, 2024
8ce5813
update to the new LightKrylov/dev API with get_size
Simkern Jun 24, 2024
f202a8d
updated dlaa_opts
Simkern Jun 24, 2024
9310a37
updated chkstep logic and dlra_opts
Simkern Jun 24, 2024
645d4bb
typo
Simkern Jun 24, 2024
96a066f
Propagated updates in the TestTypes from LightKrylov to LightROM
Simkern Jun 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@
doc

# auxiliary files
example/DLRA_laplacian2D_lti_lyapunov/output.txt
example/DLRA_laplacian2D_lti_lyapunov/laplacian.gpp
example/DLRA_laplacian2D_lti_lyapunov/*.txt
example/DLRA_laplacian2D_lti_lyapunov/*.gpp
example/DLRA_ginzburg_landau/*.txt
example/DLRA_ginzburg_landau/*.gpp

# local data
local/

# data files
*.npy
Expand Down
268 changes: 268 additions & 0 deletions example/DLRA_ginzburg_landau/ginzburg_landau_RK_lyapunov.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
module Ginzburg_Landau_RK_Lyapunov
! Standard Library.
use stdlib_optval, only : optval
! RKLIB module for time integration.
use rklib_module
! LightKrylov for linear algebra.
use LightKrylov
use LightKrylov, only : wp => dp
! Ginzburg Landau
use Ginzburg_Landau_Base
use Ginzburg_Landau_Operators
implicit none

private :: this_module
character*128, parameter :: this_module = 'Ginzburg_Landau_RK_Lyapunov'

public :: GL_mat

!-------------------------------------------
!----- LIGHTKRYLOV VECTOR TYPE -----
!-------------------------------------------

type, extends(abstract_vector_rdp), public :: state_matrix
real(wp) :: state(N**2) = 0.0_wp
contains
private
procedure, pass(self), public :: zero => matrix_zero
procedure, pass(self), public :: dot => matrix_dot
procedure, pass(self), public :: scal => matrix_scal
procedure, pass(self), public :: axpby => matrix_axpby
procedure, pass(self), public :: rand => matrix_rand
procedure, pass(self), public :: get_size => matrix_get_size
end type state_matrix

!-------------------------------
!----- RK LYAPUNOV -----
!-------------------------------

type, extends(abstract_linop_rdp), public :: RK_lyapunov
real(wp) :: tau ! Integration time.
contains
private
procedure, pass(self), public :: matvec => direct_solver_lyap
procedure, pass(self), public :: rmatvec => adjoint_solver_lyap
end type RK_lyapunov

contains

!----- TYPE-BOUND PROCEDURE FOR MATRICES -----

subroutine matrix_zero(self)
class(state_matrix), intent(inout) :: self
self%state = 0.0_wp
return
end subroutine matrix_zero

real(wp) function matrix_dot(self, vec) result(alpha)
class(state_matrix), intent(in) :: self
class(abstract_vector_rdp), intent(in) :: vec
select type(vec)
type is(state_matrix)
alpha = dot_product(self%state, weight_mat*vec%state)
end select
return
end function matrix_dot

integer function matrix_get_size(self) result(N)
class(state_matrix), intent(in) :: self
N = N**2
return
end function matrix_get_size

subroutine matrix_scal(self, alpha)
class(state_matrix), intent(inout) :: self
real(wp), intent(in) :: alpha
self%state = self%state * alpha
return
end subroutine matrix_scal

subroutine matrix_axpby(self, alpha, vec, beta)
class(state_matrix), intent(inout) :: self
class(abstract_vector_rdp), intent(in) :: vec
real(wp) , intent(in) :: alpha, beta
select type(vec)
type is(state_matrix)
self%state = alpha*self%state + beta*vec%state
end select
return
end subroutine matrix_axpby

subroutine matrix_rand(self, ifnorm)
class(state_matrix), intent(inout) :: self
logical, optional, intent(in) :: ifnorm
! internals
logical :: normalize
real(wp) :: alpha
normalize = optval(ifnorm, .true.)
call random_number(self%state)
if (normalize) then
alpha = self%norm()
call self%scal(1.0/alpha)
endif
return
end subroutine matrix_rand

subroutine GL_mat(flat_mat_out, flat_mat_in, adjoint, transpose)

!> State vector.
real(wp), dimension(:), intent(in) :: flat_mat_in
!> Time-derivative.
real(wp), dimension(:), intent(out) :: flat_mat_out
!> Adjoint
logical, optional :: adjoint
logical :: adj
logical, optional :: transpose
logical :: trans

!> Internal variables.
integer :: j
real(wp), dimension(N,N) :: mat, dmat

!> Deal with optional argument
adj = optval(adjoint,.false.)
trans = optval(transpose,.false.)

!> Sets the internal variables.
mat = reshape(flat_mat_in(1:N**2),(/N, N/))
dmat = 0.0_wp

if (adj) then
if (trans) then
do j = 1,N
call adjoint_GL(mat(:,j), dmat(j,:))
end do
else
do j = 1,N
call adjoint_GL(mat(:,j), dmat(:,j))
end do
end if
else
if (trans) then
do j = 1,N
call direct_GL(mat(:,j), dmat(j,:))
end do
else
do j = 1,N
call direct_GL(mat(:,j), dmat(:,j))
end do
end if
endif

!> Reshape for output
flat_mat_out = reshape(dmat, shape(flat_mat_in))

return
end subroutine GL_mat

!--------------------------------------
!----- WRAPPERS FOR RKLIB -----
!--------------------------------------

subroutine rhs_lyap(me, t, x_flat, f_flat)
! Time-integrator.
class(rk_class), intent(inout) :: me
! Current time.
real(wp), intent(in) :: t
! State vector.
real(wp), dimension(:), intent(in) :: x_flat
! Time-derivative.
real(wp), dimension(:), intent(out) :: f_flat

! internals
real(wp), dimension(N**2) :: x_tmp, AX_flat, XAH_flat

f_flat = 0.0_wp; AX_flat = 0.0_wp; XAH_flat = 0.0_wp; x_tmp = 0.0_wp
! A @ X
call GL_mat( AX_flat, x_flat, adjoint = .false., transpose = .false.)
! build X.T
x_tmp = reshape(transpose(reshape(x_flat, (/ N,N /))), shape(x_flat))
! build ( A @ X.T ).T = X @ A.T
call GL_mat(XAH_flat, x_tmp, adjoint = .false., transpose = .true.)
! construct Lyapunov equation
f_flat = AX_flat + XAH_flat + BBTW_flat

return
end subroutine rhs_lyap

subroutine adjoint_rhs_lyap(me, t, x_flat, f_flat)
! Time-integrator.
class(rk_class), intent(inout) :: me
! Current time.
real(wp), intent(in) :: t
! State vector.
real(wp), dimension(:), intent(in) :: x_flat
! Time-derivative.
real(wp), dimension(:), intent(out) :: f_flat

! internals
real(wp), dimension(N**2) :: x_tmp, AHX_flat, XA_flat

f_flat = 0.0_wp; AHX_flat = 0.0_wp; XA_flat = 0.0_wp; x_tmp = 0.0_wp
! A.T @ X
call GL_mat(AHX_flat, x_flat, adjoint = .true., transpose = .false.)
! build X.T
x_tmp = reshape(transpose(reshape(x_flat, (/ N,N /))), shape(x_flat))
! build ( A.T @ X.T ).T = X @ A
call GL_mat( XA_flat, x_tmp, adjoint = .true., transpose = .true.)
! construct Lyapunov equation
f_flat = AHX_flat + XA_flat + CTCW_flat

return
end subroutine adjoint_rhs_lyap

!------------------------------------------------------------------------
!----- TYPE-BOUND PROCEDURES FOR THE EXPONENTIAL PROPAGATOR -----
!------------------------------------------------------------------------

subroutine direct_solver_lyap(self, vec_in, vec_out)
! Linear Operator.
class(rk_lyapunov), intent(in) :: self
! Input vector.
class(abstract_vector_rdp), intent(in) :: vec_in
! Output vector.
class(abstract_vector_rdp), intent(out) :: vec_out

! Time-integrator.
type(rks54_class) :: prop
real(kind=wp) :: dt = 1.0_wp

select type(vec_in)
type is(state_matrix)
select type(vec_out)
type is(state_matrix)
! Initialize propagator.
call prop%initialize(n=N**2, f=rhs_lyap)
! Integrate forward in time.
call prop%integrate(0.0_wp, vec_in%state, dt, self%tau, vec_out%state)
end select
end select
return
end subroutine direct_solver_lyap

subroutine adjoint_solver_lyap(self, vec_in, vec_out)
! Linear Operator.
class(rk_lyapunov), intent(in) :: self
! Input vector.
class(abstract_vector_rdp), intent(in) :: vec_in
! Output vector.
class(abstract_vector_rdp), intent(out) :: vec_out

! Time-integrator.
type(rks54_class) :: prop
real(kind=wp) :: dt = 1.0_wp

select type(vec_in)
type is(state_matrix)
select type(vec_out)
type is(state_matrix)
! Initialize propagator.
call prop%initialize(n=N**2, f=adjoint_rhs_lyap)
! Integrate forward in time.
call prop%integrate(0.0_wp, vec_in%state, dt, self%tau, vec_out%state)
end select
end select
return
end subroutine adjoint_solver_lyap

end module Ginzburg_Landau_RK_Lyapunov
Loading
Loading