New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
solsor.F90 in trunk/NEMO/OPA_SRC/SOL – NEMO

source: trunk/NEMO/OPA_SRC/SOL/solsor.F90 @ 3

Last change on this file since 3 was 3, checked in by opalod, 20 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1MODULE solsor
2   !!======================================================================
3   !!                     ***  MODULE  solsor
4   !! Ocean solver :  Successive Over-Relaxation solver
5   !!=====================================================================
6
7   !!----------------------------------------------------------------------
8   !!   sol_sor     : Successive Over-Relaxation solver
9   !!----------------------------------------------------------------------
10   !! * Modules used
11   USE oce             ! ocean dynamics and tracers variables
12   USE dom_oce         ! ocean space and time domain variables
13   USE zdf_oce         ! ocean vertical physics variables
14   USE sol_oce         ! solver variables
15   USE in_out_manager  ! I/O manager
16   USE lib_mpp         ! distributed memory computing
17   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
18
19   IMPLICIT NONE
20   PRIVATE
21
22   !! * Routine accessibility
23   PUBLIC sol_sor              ! ???
24   !!----------------------------------------------------------------------
25   !!   OPA 9.0 , LODYC-IPSL  (2003)
26   !!----------------------------------------------------------------------
27
28CONTAINS
29     
30   SUBROUTINE sol_sor( kt, kindic )
31      !!----------------------------------------------------------------------
32      !!                  ***  ROUTINE sol_sor  ***
33      !!                 
34      !! ** Purpose :   Solve the ellipic equation for the barotropic stream
35      !!      function system (default option) or the transport divergence
36      !!      system (key_dynspg_fsc = T) using a successive-over-relaxation
37      !!      method.
38      !!       In the former case, the barotropic stream function trend has a
39      !!     zero boundary condition along all coastlines (i.e. continent
40      !!     as well as islands) while in the latter the boundary condition
41      !!     specification is not required.
42      !!
43      !! ** Method  :   Successive-over-relaxation method using the red-black
44      !!      technique. The former technique used was not compatible with
45      !!      the north-fold boundary condition used in orca configurations.
46      !!
47      !! References :
48      !!      Madec et al. 1988, Ocean Modelling, issue 78, 1-6.
49      !!
50      !! History :
51      !!        !  90-10  (G. Madec)  Original code
52      !!        !  91-11  (G. Madec)
53      !!   7.1  !  93-04  (G. Madec)  time filter
54      !!        !  96-05  (G. Madec)  merge sor and pcg formulations
55      !!        !  96-11  (A. Weaver)  correction to preconditioning
56      !!   8.5  !  02-08  (G. Madec)  F90: Free form
57      !!        !  03-02  (C. Deltel)  Red-Black SOR <== Not done yet!!!
58      !!                                                *************
59      !!----------------------------------------------------------------------
60      !! * Arguments
61      INTEGER, INTENT(  in   ) ::   kt       ! ocean time-step
62      INTEGER, INTENT( inout ) ::   kindic   ! solver indicator, < 0 if the conver-
63      !                                      ! gence is not reached: the model is
64      !                                      ! stopped in step
65      !                                      ! set to zero before the call of solsor
66
67      !! * Local declarations
68      INTEGER  ::   ji, jj, jn               ! dummy loop indices
69      REAL(wp) ::   zgwgt                    ! temporary scalar
70      !!----------------------------------------------------------------------
71     
72     
73      ! Iterative loop
74      ! ==============
75     
76      IF( kt == nit000 )  gccd(:,:) = sor * gcp(:,:,2)
77
78
79      DO jn = 1, nmax
80
81         !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
82         
83         ! boundary conditions (at each sor iteration) only cyclic b. c. are required
84#if defined key_dynspg_fsc
85# if defined key_mpp
86            ! Mpp: export boundary values to neighbouring processors
87            CALL lbc_lnk( gcx, 'S', 1. )   ! S=T with special staff ???
88# else
89            CALL lbc_lnk( gcx, 'T', 1. )
90# endif
91#else
92# if defined key_mpp
93            ! Mpp: export boundary values to neighbouring processors
94            CALL lbc_lnk( gcx, 'G', 1. )   ! G= F with special staff ???
95# else
96            CALL lbc_lnk( gcx, 'F', 1. )
97# endif
98#endif
99         
100         !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
101         
102         ! 1. Residus
103         ! ----------
104 
105         DO jj = 2, jpjm1
106            DO ji = 2, jpim1
107               gcr(ji,jj) =  gcb(ji,jj  ) -             gcx(ji  ,jj  )   &
108                                          -gcp(ji,jj,1)*gcx(ji  ,jj-1)   &
109                                          -gcp(ji,jj,2)*gcx(ji-1,jj  )   &
110                                          -gcp(ji,jj,3)*gcx(ji+1,jj  )   &
111                                          -gcp(ji,jj,4)*gcx(ji  ,jj+1)
112            END DO
113         END DO
114
115         !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
116         
117         ! 1.1 Boundary conditions (at each sor iteration) only cyclic b. c. are required
118#if defined key_dynspg_fsc
119#   if defined key_mpp
120            ! Mpp: export boundary values to neighbouring processors
121            CALL lbc_lnk( gcr, 'S', 1. )
122#   else
123            ! mono- or macro-tasking: W-point, >0, 2D array, no slab
124            CALL lbc_lnk( gcr, 'T', 1. )
125#   endif
126#else
127#   if defined key_mpp
128            ! Mpp: export boundary values to neighbouring processors
129            CALL lbc_lnk( gcr, 'G', 1. )
130#   else
131            ! mono- or macro-tasking: W-point, >0, 2D array, no slab
132            CALL lbc_lnk( gcr, 'F', 1. )
133#   endif
134#endif
135
136         ! 1.2 Successive over relaxation
137         
138         DO jj = 2, jpj
139            DO ji = 1, jpi
140               gcr(ji,jj) = gcr(ji,jj) - sor*gcp(ji,jj,1)*gcr(ji,jj-1)
141            END DO
142            DO ji = 2, jpi
143               gcr(ji,jj) = gcr(ji,jj) - sor*gcp(ji,jj,2)*gcr(ji-1,jj)
144            END DO
145         END DO
146         
147         !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
148         
149         ! gcx guess
150         
151         DO jj = 2, jpjm1
152            DO ji = 1, jpi
153               gcx(ji,jj)  = (gcx(ji,jj)+sor*gcr(ji,jj))*bmask(ji,jj)
154            END DO
155         END DO
156         
157         !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
158         
159         ! boundary conditions (at each sor iteration) only cyclic b. c. are required
160#if defined key_dynspg_fsc
161#   if defined key_mpp
162         ! Mpp: export boundary values to neighbouring processors
163         CALL lbc_lnk( gcx, 'S', 1. )
164#   else
165         ! mono- or macro-tasking: W-point, >0, 2D array, no slab
166         CALL lbc_lnk( gcx, 'T', 1. )
167#   endif
168#else
169#   if defined key_mpp
170         ! Mpp: export boundary values to neighbouring processors
171         CALL lbc_lnk( gcx, 'G', 1. )
172#   else
173         ! mono- or macro-tasking: W-point, >0, 2D array, no slab
174         CALL lbc_lnk( gcx, 'F', 1. )
175#   endif
176#endif
177         
178         ! maximal residu (old exit test on the maximum value of residus)
179         !
180         ! imax = isamax( jpi*jpj, gcr, 1 )
181         
182         ! avoid an out of bound in no bounds compilation
183         
184         ! iimax1 = mod( imax, jpi )
185         ! ijmax1 = int( float(imax) / float(jpi)) + 1
186         ! resmax = abs( gcr(iimax1,ijmax1) )
187         
188         ! relative precision
189         
190         rnorme = 0.
191         DO jj = 1, jpj
192            DO ji = 1, jpi
193               zgwgt = gcdmat(ji,jj) * gcr(ji,jj)
194               rnorme= rnorme + gcr(ji,jj)*zgwgt
195            END DO
196         END DO
197         
198#if defined key_mpp
199         ! mpp sum over all the global domain
200         CALL  mpp_sum( rnorme )
201#endif
202         
203         ! test of convergence
204         ! old test (either res<resmax or jn=nmax)
205         !           IF( res < resmax .OR. jn == nmax ) THEN
206         ! relative precision
207         IF( rnorme < epsr .OR. jn == nmax ) THEN
208            res = SQRT( rnorme )
209            niter = jn
210            ncut = 999
211         ENDIF
212         
213         !****
214         !     IF(lwp)WRITE(numsol,9300) jn, res, sqrt( epsr ) / eps
2159300     FORMAT('          niter :',i4,' res :',e20.10,' b :',e20.10)
216         !****
217         
218         !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
219         
220         ! indicator of non-convergence or explosion
221         
222         IF( jn == nmax .OR. SQRT(epsr)/eps > 1.e+20 ) kindic = -2
223         IF( ncut == 999 ) GOTO 999
224         
225         
226         ! END of iterative loop
227         ! =====================
228         
229      END DO
230     
231     
232999   CONTINUE
233     
234     
235      !  2. Output in gcx
236      !  -----------------
237     
238      ! boundary conditions (est-ce necessaire? je ne crois pas!!!!)
239     
240#if defined key_dynspg_fsc
241# if defined key_mpp
242      ! Mpp: export boundary values to neighbouring processors
243      CALL lbc_lnk( gcx, 'S', 1. )
244# else
245      IF( nperio /= 0 ) THEN
246         CALL lbc_lnk( gcx, 'T', 1. )
247      ENDIF
248# endif
249#else
250# if defined key_mpp
251      ! Mpp: export boundary values to neighbouring processors
252      CALL lbc_lnk( gcx, 'G', 1. )
253# else
254      IF( nperio /= 0 ) THEN
255         CALL lbc_lnk( gcx, 'F', 1. )
256      ENDIF
257# endif
258#endif
259     
260   END SUBROUTINE sol_sor
261
262   !!=====================================================================
263END MODULE solsor
Note: See TracBrowser for help on using the repository browser.