ROMS
Loading...
Searching...
No Matches
mod_storage.F
Go to the documentation of this file.
1#include "cppdefs.h"
3
4#if defined PROPAGATOR
5!
6!git $Id$
7!================================================== Hernan G. Arango ===
8! Copyright (c) 2002-2025 The ROMS Group !
9! Licensed under a MIT/X style license !
10! See License_ROMS.md !
11!=======================================================================
12! !
13! ROMS Generalized Stability Theory (GST) Analysis: ARPACK !
14! !
15! LworkL Size of Arnoldi iterations work array SworkL. !
16! Lrvec ARPACK logical to compute converged Ritz values. !
17! NCV Number of Lanczos vectors to compute. !
18! NEV Number of eigenvalues to compute. !
19! Bvec Lanczos/Arnoldi basis vectors. !
20! RvalueR Real Ritz eigenvalues. !
21! RvalueI Imaginary Ritz eigenvalues. !
22! Rvector Real Ritz eigenvectors. !
23! Swork FULL state work array used in distributed memory !
24! communications. !
25! SworkR FULL state work array used to compute the ROMS state !
26! eigenvectors. !
27! SworkD State work array for ARPACK reverse communications. !
28! SworkEV ARPACK work array. !
29! SworkL ARPACK work array. !
30! bmat ARPACK eigenvalue value problem identifier: !
31! bmat='I' standard eigenvalue problem !
32! bmat='G' generalized eigenvalue problem !
33! howmany ARPACK form of basis functions identifier: !
34! howmany='A' compute NEV Ritz vectors !
35! howmany='P' compute NEV Schur vectors !
36! howmany='S' compute some Ritz vectors using select !
37! ido ARPACK reverse communications flag (input/output). !
38! iparam ARPACK input/output integer parameters. !
39! ipntr ARPACK pointer to mark the starting location in SworkD !
40! and SworkK arrays used in the Arnoldi iterations. !
41! info ARPACK Information (input) and error flag (output). !
42! norm Euclidean norm. !
43! pick ARPACK logical switch of Ritz vectors to compute. !
44! resid Initial/final residual vector. !
45! sigmaR ARPACK real part of the shifts (not referenced). !
46! sigmaI ARPACK imaginary part of the shifts (not referenced). !
47# ifdef SO_SEMI
48! so_state Stochastic optimals adjoint state surface forcing !
49! vector sample in time. !
50# endif
51! which ARPACK Ritz eigenvalues to compute identifier: !
52! which='LA' compute NEV largest (algebraic) !
53! which='SA' compute NEV smallest (algebraic) !
54! which='LM' compute NEV largest in magnitude !
55! which='SM' compute NEV smallest in magnitude !
56! which='BE' compute NEV from each end of spectrum !
57! !
58!=======================================================================
59!
60 USE mod_param
61!
62 implicit none
63!
64 PUBLIC :: allocate_storage
65 PUBLIC :: deallocate_storage
66!
67!-----------------------------------------------------------------------
68! Define T_STORAGE structure and other module variables.
69!-----------------------------------------------------------------------
70!
71! State work arrays structure for nested grids.
72!
74
75 real(r8), pointer :: bvec(:,:) ! [Nstr:Nend,NCV]
76 real(r8), pointer :: rvector(:,:) ! [Nstr:Nend,NEV+1]
77 real(r8), pointer :: sworkd(:) ! [3*Nstate]
78 real(r8), pointer :: resid(:) ! [Nstr:Nend]
79# ifdef STOCHASTIC_OPT
80 real(r8), pointer :: ad_work(:) ! [Mstate]
81# endif
82# if defined STOCHASTIC_OPT && defined HESSIAN_SO
83 real(r8), pointer :: my_state(:) ! [Nstr:Nend]
84# endif
85# ifdef SO_SEMI
86 real(r8), pointer :: so_state(:,:) ! [Nstr:Nend,Nsemi]
87# endif
88
89 END TYPE t_storage
90!
91 TYPE (t_storage), allocatable :: storage(:)
92!
93! ARPACK logical switches.
94!
95 logical :: lrvec ! Ritz values switch
96 logical, allocatable :: pick(:,:) ! Ritz vectors, [NCV,Ngrids]
97!
98! Eigenproblem parameters.
99!
100 integer :: ncv ! number of Lanczos vectors
101 integer :: nev ! number of eigenvalues
102 integer :: lworkl ! size of array SworkL
103
104 integer, allocatable :: lworkd(:) ! size of array SworkD
105!
106! ARPACK integer parameters and flags.
107!
108 integer, allocatable :: iparam(:,:) ! eigenproblem parameters
109 integer, allocatable :: ipntr(:,:) ! index for work arrays
110 integer, allocatable :: ido(:) ! reverse communication flag
111 integer, allocatable :: info(:) ! information and error flag
112!
113! ARPACK floating-point parameters.
114!
115 real(r8) :: sigmai ! real part shifts
116 real(r8) :: sigmar ! imaginary part shifts
117!
118! ARPACK character parameters.
119!
120 character (len=1) :: bmat ! eigenvalue problem ID
121 character (len=1) :: howmany ! basis functions ID
122 character (len=2) :: which ! Ritz values ID
123!
124! ARPACK work arrays.
125!
126 real(r8), allocatable :: rvaluer(:,:) ! [NEV+1,Ngrids]
127 real(r8), allocatable :: rvaluei(:,:) ! [NEV+1,Ngrids]
128 real(r8), allocatable :: norm(:,:) ! [NEV+1,Ngrids]
129 real(r8), allocatable :: sworkl(:,:) ! [LworkL,Ngrids]
130 real(r8), allocatable :: sworkev(:,:) ! [3*NCV,Ngrids]
131# ifdef DISTRIBUTE
132 real(r8), allocatable :: swork(:) ! [Mstate]
133# endif
134 real(r8), pointer :: sworkr(:) ! [Mstate]
135!
136! ARPACK private common blocks containing parameters needed for
137! checkpoiniting. The original include files "i_aupd.h" and
138! "idaup2.h" have several parameters in their commom blocks. All
139! these values are compacted here in vector arrays to allow IO
140! manipulations during checkpointing.
141!
142 integer :: iaitr(8), iaup2(8), iaupd(20)
143 logical :: laitr(5), laup2(5)
144 real(r8) :: raitr(8), raup2(2)
145!
146 common /i_aupd/ iaupd
147# ifdef DOUBLE_PRECISION
148 common /idaitr/ iaitr
149 common /ldaitr/ laitr
150 common /rdaitr/ raitr
151 common /idaup2/ iaup2
152 common /ldaup2/ laup2
153 common /rdaup2/ raup2
154# else
155 common /isaitr/ iaitr
156 common /lsaitr/ laitr
157 common /rsaitr/ raitr
158 common /isaup2/ iaup2
159 common /lsaup2/ laup2
160 common /rsaup2/ raup2
161# endif
162!
163! ARPACK debugging common block.
164!
165 integer :: logfil, ndigit, mgetv0
169!
170 common /debug/ &
171 & logfil, ndigit, mgetv0, &
175!
176 CONTAINS
177!
179!
180!=======================================================================
181! !
182! This routine allocates and initialize module variables. For now, !
183! only non-nested applications are considered. !
184! !
185!=======================================================================
186!
187 USE mod_scalars
188!
189! Local variable declarations
190!
191 integer :: i, j, ng
192
193 integer, allocatable :: mstr(:), mend(:)
194!
195 real(r8), parameter :: inival = 0.0_r8
196!
197!-----------------------------------------------------------------------
198! Allocate module variables.
199!-----------------------------------------------------------------------
200!
201! Allocate local dimension parameters.
202!
203 allocate ( mstr(ngrids) )
204 allocate ( mend(ngrids) )
205!
206! Allocate parameters associated with nested grids.
207!
208 allocate ( ido(ngrids) )
209 allocate ( info(ngrids) )
210 allocate ( lworkd(ngrids) )
211
212 allocate ( iparam(11,ngrids) )
213# if defined AFT_EIGENMODES || defined FT_EIGENMODES
214 allocate ( ipntr(14,ngrids) )
215# else
216 allocate ( ipntr(11,ngrids) )
217# endif
218!
219! Determine size of work array SworkL:
220!
221# if defined OPT_PERTURBATION
222 lworkl=ncv*(ncv+8)
223# elif defined HESSIAN_SV
224 lworkl=ncv*(ncv+8)
225# elif defined HESSIAN_FSV
226 lworkl=ncv*(ncv+8)
227# elif defined FORCING_SV
228 lworkl=ncv*(ncv+8)
229# elif defined STOCHASTIC_OPT
230 lworkl=ncv*(ncv+8)
231# elif defined SO_SEMI
232 lworkl=ncv*(ncv+8)
233# elif defined FT_EIGENMODES || defined AFT_EIGENMODES
234 lworkl=3*ncv*ncv+6*ncv
235# endif
236# ifdef SO_SEMI
237 DO ng=1,ngrids
238 nsemi(ng)=1+ntimes(ng)/nadj(ng)
239 END DO
240# endif
241!
242! Set local dimensions of storage arrays according to the propagator
243! driver.
244!
245 DO ng=1,ngrids
246# if defined HESSIAN_FSV || defined HESSIAN_SO || defined HESSIAN_SV
247 mstr(ng)=1
248 mend(ng)=ninner
249 lworkd(ng)=3*ninner
250# else
251 mstr(ng)=nstr(ng)
252 mend(ng)=nend(ng)
253 lworkd(ng)=3*nstate(ng)
254# endif
255 END DO
256!
257! Allocate structure.
258!
259 allocate ( storage(ngrids) )
260
261 DO ng=1,ngrids
262 allocate ( storage(ng) % Bvec(mstr(ng):mend(ng),ncv) )
263 dmem(ng)=dmem(ng)+real((mend(ng)-mstr(ng))*ncv,r8)
264
265 allocate ( storage(ng) % Rvector(mstr(ng):mend(ng),nev+1) )
266 dmem(ng)=dmem(ng)+real((mend(ng)-mstr(ng))*(nev+1),r8)
267
268 allocate ( storage(ng) % SworkD(lworkd(ng)) )
269 dmem(ng)=dmem(ng)+real(lworkd(ng),r8)
270
271 allocate ( storage(ng) % resid(mstr(ng):mend(ng)) )
272 dmem(ng)=dmem(ng)+real(mend(ng)-mstr(ng),r8)
273
274# ifdef STOCHASTIC_OPT
275 allocate ( storage(ng) % ad_Work(maxval(mstate)) )
276 dmem(ng)=dmem(ng)+real(maxval(mstate),r8)
277# endif
278
279# if defined STOCHASTIC_OPT && defined HESSIAN_SO
280 allocate ( storage(ng) % my_state(nstr(ng):nend(ng)) )
281 dmem(ng)=dmem(ng)+real(nend(ng)-nstr(ng),r8)
282# endif
283
284# ifdef SO_SEMI
285 allocate ( storage(ng) % so_state(mstr(ng):mend(ng),nsemi(ng)) )
286 dmem(ng)=dmem(ng)+real((mend(ng)-mstr(ng))*nsemi(ng),r8)
287# endif
288 END DO
289!
290! Allocate other arrays.
291!
292 ng=1
293!
294 allocate ( pick(ncv,ngrids) )
295 dmem(ng)=dmem(ng)+real(ncv*ngrids,r8)
296
297 allocate ( norm(nev+1,ngrids) )
298 dmem(ng)=dmem(ng)+real((nev+1)*ngrids,r8)
299
300 allocate ( rvaluer(nev+1,ngrids) )
301 dmem(ng)=dmem(ng)+real((nev+1)*ngrids,r8)
302
303 allocate ( rvaluei(nev+1,ngrids) )
304 dmem(ng)=dmem(ng)+real((nev+1)*ngrids,r8)
305
306 allocate ( sworkev(3*ncv,ngrids) )
307 dmem(ng)=dmem(ng)+3.0_r8*real(ncv,r8)
308
309 allocate ( sworkl(lworkl,ngrids) )
310 dmem(ng)=dmem(ng)+real(lworkl*ngrids,r8)
311
312 allocate ( sworkr(maxval(mstate)) )
313 dmem(ng)=dmem(ng)+real(maxval(mstate),r8)
314
315# ifdef DISTRIBUTE
316 allocate ( swork(maxval(mstate)) )
317 dmem(ng)=dmem(ng)+real(maxval(mstate),r8)
318# endif
319!
320!-----------------------------------------------------------------------
321! Initialize module variables.
322!-----------------------------------------------------------------------
323!
324 iparam=0
325 ipntr=0
326
327 DO ng=1,ngrids
328 DO j=1,ncv
329 pick(j,ng) = .true.
330 DO i=mstr(ng),mend(ng)
331 storage(ng) % Bvec(i,j) = inival
332 END DO
333 END DO
334 DO j=1,nev+1
335 norm(j,ng) = inival
336 rvaluer(j,ng) = inival
337 rvaluei(j,ng) = inival
338 DO i=mstr(ng),mend(ng)
339 storage(ng) % Rvector(i,j) = inival
340 END DO
341 END DO
342 DO i=mstr(ng),mend(ng)
343 storage(ng) % resid(i) = inival
344 END DO
345# ifdef STOCHASTIC_OPT
346 DO i=1,maxval(mstate)
347 storage(ng) % ad_Work(i) = inival
348 END DO
349# endif
350# if defined STOCHASTIC_OPT && defined HESSIAN_SO
351 DO i=nstr(ng),nend(ng)
352 storage(ng) % my_state(i) = inival
353 END DO
354# endif
355# ifdef SO_SEMI
356 DO j=1,nsemi(ng)
357 DO i=mstr(ng),mend(ng)
358 storage(ng) % so_state(i,j) = inival
359 END DO
360 END DO
361# endif
362 END DO
363 DO i=1,maxval(mstate)
364 sworkr(i) = inival
365 END DO
366# ifdef DISTRIBUTE
367 DO i=1,maxval(mstate)
368 swork(i) = inival
369 END DO
370# endif
371!
372 DO ng=1,ngrids
373 DO i=1,lworkd(ng)
374 storage(ng) % SworkD(i) = inival
375 END DO
376 DO i=1,3*ncv
377 sworkev(i,ng) = inival
378 END DO
379 DO i=1,lworkl
380 sworkl(i,ng) = inival
381 END DO
382 END DO
383!
384 RETURN
385 END SUBROUTINE allocate_storage
386!
387 SUBROUTINE deallocate_storage (ng)
388!
389!=======================================================================
390! !
391! This routine deallocates and initialize module variables. !
392! !
393!=======================================================================
394!
395 USE mod_param, ONLY : ngrids
396!
397! Imported variable declarations
398!
399 integer, intent(in) :: ng
400
401# ifdef SUBOBJECT_DEALLOCATION
402!
403!-----------------------------------------------------------------------
404! Deallocate each variable in the derived-type T_STORAGE structure
405! separately.
406!-----------------------------------------------------------------------
407!
408 IF (associated(storage(ng)%Bvec)) THEN
409 deallocate ( storage(ng)%Bvec )
410 END IF
411
412 IF (associated(storage(ng)%Rvector)) THEN
413 deallocate ( storage(ng)%Rvector )
414 END IF
415
416 IF (associated(storage(ng)%SworkD)) THEN
417 deallocate ( storage(ng)%SworkD )
418 END IF
419
420 IF (associated(storage(ng)%resid)) THEN
421 deallocate ( storage(ng)%resid )
422 END IF
423
424# ifdef STOCHASTIC_OPT
425 IF (associated(storage(ng)%ad_Work)) THEN
426 deallocate ( storage(ng)%ad_Work )
427 END IF
428# endif
429
430# if defined STOCHASTIC_OPT && defined HESSIAN_SO
431 IF (associated(storage(ng)%my_state)) THEN
432 deallocate ( storage(ng)%my_state )
433 END IF
434# endif
435
436# ifdef SO_SEMI
437 IF (associated(storage(ng)%so_state)) THEN
438 deallocate ( storage(ng)%so_state )
439 END IF
440# endif
441# endif
442!
443!-----------------------------------------------------------------------
444! Deallocate derived-type STORAGE structure.
445!-----------------------------------------------------------------------
446!
447 IF (ng.eq.ngrids) THEN
448 IF (allocated(storage)) deallocate ( storage )
449 END IF
450!
451!-----------------------------------------------------------------------
452! Deallocate other variables in module.
453!-----------------------------------------------------------------------
454!
455 IF (allocated(mstr)) deallocate ( mstr )
456 IF (allocated(mend)) deallocate ( mend )
457 IF (allocated(ido)) deallocate ( ido )
458 IF (allocated(info)) deallocate ( info )
459 IF (allocated(lworkd)) deallocate ( lworkd )
460 IF (allocated(iparam)) deallocate ( iparam )
461 IF (allocated(ipntr)) deallocate ( ipntr )
462 IF (allocated(pick)) deallocate ( pick )
463 IF (allocated(norm)) deallocate ( norm )
464 IF (allocated(rvaluer)) deallocate ( rvaluer )
465 IF (allocated(rvaluei)) deallocate ( rvaluei )
466 IF (allocated(sworkev)) deallocate ( sworkev )
467 IF (allocated(sworkl)) deallocate ( sworkl )
468 IF (allocated(sworkr)) deallocate ( sworkr )
469# ifdef DISTRIBUTE
470 IF (allocated(swork)) deallocate ( swork )
471# endif
472!
473 RETURN
474 END SUBROUTINE deallocate_storage
475#endif
476 END MODULE mod_storage
integer, dimension(:), allocatable nstate
Definition mod_param.F:645
integer, dimension(:), allocatable mstate
Definition mod_param.F:644
integer, dimension(:), allocatable nstr
Definition mod_param.F:646
real(r8), dimension(:), allocatable dmem
Definition mod_param.F:137
integer, dimension(:), allocatable nsemi
Definition mod_param.F:655
integer ngrids
Definition mod_param.F:113
integer, dimension(:), allocatable nend
Definition mod_param.F:647
integer ninner
integer, dimension(:), allocatable ntimes
integer, dimension(:), allocatable nadj
integer mngets
integer msaup2
integer mcaupd
integer mneigh
real(r8), dimension(2) raup2
integer, dimension(8) iaup2
integer, dimension(:), allocatable ido
integer, dimension(20) iaupd
integer mgetv0
real(r8), dimension(:,:), allocatable rvaluei
integer mcgets
integer mcapps
real(r8), dimension(:,:), allocatable sworkl
integer, dimension(:,:), allocatable ipntr
integer ncv
integer mnaitr
real(r8), dimension(8) raitr
character(len=1) howmany
logical, dimension(5) laup2
logical lrvec
Definition mod_storage.F:95
real(r8), dimension(:,:), allocatable sworkev
integer msaupd
real(r8) sigmai
integer mnapps
integer mnaup2
character(len=1) bmat
integer nev
integer mcaitr
integer mceigh
type(t_storage), dimension(:), allocatable storage
Definition mod_storage.F:91
real(r8), dimension(:,:), allocatable norm
integer, dimension(:), allocatable info
subroutine, public allocate_storage
character(len=2) which
integer lworkl
real(r8), dimension(:), allocatable swork
integer, dimension(:,:), allocatable iparam
integer mseigt
integer msapps
integer ndigit
integer msgets
logical, dimension(:,:), allocatable pick
Definition mod_storage.F:96
real(r8) sigmar
integer logfil
real(r8), dimension(:), pointer sworkr
real(r8), dimension(:,:), allocatable rvaluer
subroutine, public deallocate_storage(ng)
integer mneupd
integer mcaup2
integer mnaupd
integer, dimension(:), allocatable lworkd
integer, dimension(8) iaitr
integer msaitr
logical, dimension(5) laitr
integer mceupd
integer mseupd