The TELEMAC-MASCARET system  trunk
gracjg.F
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE gracjg
3 ! *****************
4 !
5  &(x, a,b , mesh, d,ad,g,r, cfg,infogr,aux)
6 !
7 !***********************************************************************
8 ! BIEF V7P1
9 !***********************************************************************
10 !
11 !brief SOLVES THE LINEAR SYSTEM A X = B
12 !+ USING THE CONJUGATE GRADIENT METHOD.
13 !code
14 !+-----------------------------------------------------------------------
15 !+ PRECONDITIONING
16 !+-----------------------------------------------------------------------
17 !+ CFG%PRECON VALUE I MEANING
18 !+-----------------------------------------------------------------------
19 !+ I
20 !+ 0 OR 1 I NO PRECONDITIONING
21 !+ I
22 !+ 2 I DIAGONAL PRECONDITIONING USING THE MATRIX
23 !+ I DIAGONAL
24 !+ 3 I BLOCK-DIAGONAL PRECONDITIONING
25 !+ I
26 !+ 5 I DIAGONAL PRECONDITIONING USING THE ABSOLUTE
27 !+ I VALUE OF THE MATRIX DIAGONAL
28 !+ I
29 !+ 7 I CROUT EBE PRECONDITIONING
30 !+ I
31 !+ 11 I GAUSS-SEIDEL EBE PRECONDITIONING
32 !+ I
33 !+-----------------------------------------------------------------------
34 !
35 !history J-M HERVOUET (LNH)
36 !+ 06/10/08
37 !+ V5P9
38 !+
39 !
40 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
41 !+ 13/07/2010
42 !+ V6P0
43 !+ Translation of French comments within the FORTRAN sources into
44 !+ English comments
45 !
46 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
47 !+ 21/08/2010
48 !+ V6P0
49 !+ Creation of DOXYGEN tags for automated documentation and
50 !+ cross-referencing of the FORTRAN sources
51 !
52 !history J-M HERVOUET (EDF LAB, LNHE)
53 !+ 10/06/2015
54 !+ V7P1
55 !+ CALL PARMOY removed, and stop if Crout preconditionning is asked
56 !+ in parallel.
57 !
58 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59 !| A |-->| MATRIX OF THE SYSTEM
60 !| AD |<->| WORK ARRAY: MATRICE A MULTIPLIED BY D.
61 !| AUX |-->| MATRIX FOR PRECONDITIONING.
62 !| B |-->| RIGHT-HAND SIDE OF THE SYSTEM
63 !| CFG |-->| STRUCTURE OF SOLVER CONFIGURATION
64 !| D |<->| WORK ARRAY: DIRECTION OF DESCENT.
65 !| G |<->| DESCENT GRADIENT.
66 !| INFOGR |-->| IF YES, PRINT A LOG.
67 !| MESH |-->| MESH STRUCTURE.
68 !| R |<->| RESIDUAL (MAY BE IN THE SAME MEMORY SPACE AS
69 !| | | GRADIENT DEPENDING ON CONDITIONING)
70 !| X |<->| INITIAL VALUE, THEN SOLUTION
71 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72 !
75  USE bief, ex_gracjg => gracjg
76 !
77  IMPLICIT NONE
78 !
79 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80 !
81  TYPE(slvcfg), INTENT(INOUT) :: CFG
82  TYPE(bief_obj), INTENT(INOUT) :: B
83  TYPE(bief_obj), INTENT(INOUT) :: D,AD,G,R,X
84  TYPE(bief_mesh), INTENT(INOUT) :: MESH
85  TYPE(bief_obj), INTENT(IN) :: A
86  TYPE(bief_obj), INTENT(INOUT) :: AUX
87  LOGICAL, INTENT(IN) :: INFOGR
88 !
89 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90 !
91  INTEGER M
92 !
93  DOUBLE PRECISION XL,RMRM,RMDM,RMGM,TESTL
94  DOUBLE PRECISION BETA,RO,DAD,RM1GM1,STO1,C
95 !
96  LOGICAL RELAT,PREC,CROUT,GSEB,PRE3D,PREBE
97 !
98  DOUBLE PRECISION, PARAMETER :: RMIN = 1.d-15
99 !
100 !-----------------------------------------------------------------------
101 !
102  LOGICAL :: FINISH
103 !
104 #if defined COMPAD_DCO_T1S || COMPAD_DCO_T1V
105  INTEGER :: DRV_ELMS
106  DOUBLE PRECISION :: DRV_ERR
107  DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: DRV0, DRV1
108 #endif
109 #if defined COMPAD_DCO_T1V
110  INTEGER :: T1V_NOD,I
111 #endif
112 !
113 !-----------------------------------------------------------------------
114 !
115  INTRINSIC sqrt
116 !
117 !-----------------------------------------------------------------------
118 !
119 ! INITIALISES
120 !
121  gracjg_cnt = gracjg_cnt + 1
122 #if defined COMPAD_DCO_T1S || COMPAD_DCO_T1V
123 ! WRITE(LU,*) 'AD LINEAR SOLVER RESET DERIVATIVES :: ',
124 ! & AD_LINSOLV_RESETDERIV
125 ! WRITE(LU,*) 'AD LINEAR SOLVER DERIVATIVE CONVERGENCE :: ',
126 ! & AD_LINSOLV_DERIVATIVE_CONVERGENCE
127 !
128 ! 1. RESET INCOMING TANGENTS TO ZERO TO AVOID DEPENDENCY OF OVERALL
129 ! TANGENTS FROM INITIAL SOLUTIONS FOR FIRST CONJUGADE GRADIENT
130 !! COMPAD-DCO BEGIN JR2016
131  IF (ad_linsolv_resetderiv ) THEN
132 # if defined COMPAD_DCO_T1S
133  CALL dco_t1s_set( x%ADR(1)%P%R, 0.d0, 1 )
134 # endif
135 # if defined COMPAD_DCO_T1V
136  t1v_nod = dco_t1v_get_nod()
137 ! WRITE(LU,*) 'T1V NOD :: ',t1V_NOD
138  DO i=1, t1v_nod
139  CALL dco_t1v_set( x%ADR(1)%P%R, 0.d0, 1, i )
140  END DO
141 # endif
142  END IF
143 !! COMPAD-DCO original code
144 !! CALL DCO_T1S_SET( X%ADR(1)%P%R, 0.D0, 1 )
145 !! COMPAD-DCO END JR2016
146 ! BY SETTING X TO A FIXED STARTING VALUE WE DISABLE THE RESTART
147 ! FROM THE PREVISOU CG SOLUTION, AND SETTING TANGENTS TO ZERO TOO
149 !
150 ! 2. PREPARE STORAGE OF GRADIENTS FOR TERMINATION TEST
151  drv_elms = x%ADR(1)%P%DIM1
152  ALLOCATE( drv0(drv_elms), drv1(drv_elms))
153 !
154 ! 3. STORE TANGENT OF X0
155 # if defined COMPAD_DCO_T1S
156  CALL dco_t1s_get( x%ADR(1)%P%R, drv0, 1 )
157 # endif
158 # if defined COMPAD_DCO_T1V
159  CALL dco_t1v_get( x%ADR(1)%P%R, drv0, 1, 1 )
160 # endif
161 !
162 #endif
163 !
164 !
165  sto1 = 0.d0
166  crout =.false.
167  IF(07*(cfg%PRECON/07).EQ.cfg%PRECON) crout=.true.
168  gseb=.false.
169  IF(11*(cfg%PRECON/11).EQ.cfg%PRECON) gseb=.true.
170  prebe=.false.
171  IF(13*(cfg%PRECON/13).EQ.cfg%PRECON) prebe=.true.
172  pre3d=.false.
173  IF(17*(cfg%PRECON/17).EQ.cfg%PRECON) pre3d=.true.
174  prec=.false.
175  IF(crout.OR.gseb.OR.prebe.OR.pre3d) prec=.true.
176 !
177 !-----------------------------------------------------------------------
178 ! INITIALISES
179 !-----------------------------------------------------------------------
180 !
181  m = 0
182 !
183 ! NORMALISES THE SECOND MEMBER TO COMPUTE THE RELATIVE PRECISION:
184 !
185  xl = p_dots(b,b,mesh)
186 !
187 ! OLIVIER BOITEAU'S (SINETICS) TEST : SECOND MEMBER TOO SMALL
188 ! ==> UNKNOWN = 0
189 !
190  testl=sqrt(xl)
191  IF(testl.LT.rmin) THEN
192  CALL os('X=0 ',x=x)
193  IF(infogr) THEN
194  WRITE(lu,106) testl
195  ENDIF
196  GOTO 1000
197  ENDIF
198 !
199  IF(xl.LT.1.d0) THEN
200  xl = 1.d0
201  relat = .false.
202  ELSE
203  relat = .true.
204  ENDIF
205 !
206 ! COMPUTES THE INITIAL RESIDUAL AND POSSIBLY EXITS:
207 !
208  CALL matrbl( 'X=AY ',r,a,x, c,mesh)
209 !
210  CALL os('X=X-Y ', x=r, y=b)
211  rmrm = p_dots(r,r,mesh)
212  rmgm = rmrm
213 !
214  IF (rmrm.LT.cfg%EPS**2*xl) GO TO 900
215 !
216 !-----------------------------------------------------------------------
217 ! PRECONDITIONING :
218 !-----------------------------------------------------------------------
219 !
220  IF(prec) THEN
221 ! COMPUTES C G0 = R0
222  IF(crout.OR.gseb.OR.prebe) THEN
223  IF(ncsize.GT.1) THEN
224  WRITE(lu,*) 'NO CROUT PRECONDITIONNING IN PARALLEL'
225  CALL plante(1)
226  stop
227  ENDIF
228  CALL downup( g, aux , r , 'D' , mesh )
229  ELSEIF(pre3d) THEN
230  CALL cpstvc(r%ADR(1)%P,g%ADR(1)%P)
231  CALL trid3d(aux%X%R,g%ADR(1)%P%R,r%ADR(1)%P%R,
232  & mesh%NPOIN,bief_nbpts(11,mesh))
233  ENDIF
234 ! COMPUTES RMGM AND STORES
235  rmgm = p_dots(r,g,mesh)
236  sto1 = rmgm
237  ENDIF
238 !
239 !-----------------------------------------------------------------------
240 ! COMPUTES THE DIRECTION OF INITIAL DESCENT:
241 !-----------------------------------------------------------------------
242 !
243  CALL os('X=Y ', x=d, y=g)
244 !
245 !-----------------------------------------------------------------------
246 ! COMPUTES THE INITIAL PRODUCT A D :
247 !-----------------------------------------------------------------------
248 !
249  CALL matrbl( 'X=AY ',ad,a,d,c,mesh)
250 !
251 !-----------------------------------------------------------------------
252 ! COMPUTES INITIAL RO :
253 !-----------------------------------------------------------------------
254 !
255  dad = p_dots(d,ad,mesh)
256  ro = rmgm / dad
257 ! USES RMGM BECAUSE HERE D0=G0
258 !
259 !-----------------------------------------------------------------------
260 !
261 ! COMPUTES X1 = X0 - RO * D
262 !
263  CALL os('X=X+CY ',x=x,y=d,c=-ro)
264 !
265 ! ALGORITHMIC DIFFERENTIATION
266 ! TAKE TANGENT OF X1 IF WE ARE IN DCO_T1S MODE AND STORE IT
267 #if defined COMPAD_DCO_T1S
268  CALL dco_t1s_get( x%ADR(1)%P%R, drv1, 1 )
269 #endif
270 #if defined COMPAD_DCO_T1V
271  CALL dco_t1v_get( x%ADR(1)%P%R, drv1, 1, 1 )
272 #endif
273 !
274 !-----------------------------------------------------------------------
275 ! ITERATIONS LOOP:
276 !-----------------------------------------------------------------------
277 !
278 2 m = m + 1
279 !
280 !-----------------------------------------------------------------------
281 ! COMPUTES THE RESIDUAL : R(M) = R(M-1) - RO(M-1) A D(M-1)
282 !-----------------------------------------------------------------------
283 !
284  CALL os('X=X+CY ',x=r,y=ad,c=-ro)
285 !
286 ! SOME VALUES WILL CHANGE IN CASE OF PRECONDITIONING
287 !
288  rm1gm1 = rmgm
289  rmrm = p_dots(r,r,mesh)
290  rmdm = rmrm
291  rmgm = rmrm
292 !
293 ! CHECKS END:
294 !
295 ! IF(RMRM.LE.XL*CFG%EPS**2) GO TO 900
296  finish = rmrm.LE.xl*cfg%EPS**2
297 #if defined COMPAD_DCO_T1S || COMPAD_DCO_T1V
298 ! CHECK DIFFERENCE BETWEEN TANGENTS OF LAST TWO STEPS
299 ! 1. SET TO ZERO TO AVOID ADDTIONAL TEST
300  drv_err = 0.d0
301 ! 2a. ABSOLUTE CHANGE TO LAST STEP
302  drv_err = sum( drv1 - drv0 )**2
303 ! 2b. RELATIVE CHANGE TO LAST STEP
304 ! DRV_ERR = SUM( DRV0*DRV0 )
305 ! IF ( DRV_ERR .GT. 0.0 ) THEN
306 ! DRV_ERR = SUM( (DRV1 - DRV0 )**2 ) / DRV_ERR
307 ! ENDIF
308 ! 3. TEST CONVERGENCE
310  finish = finish .AND. (drv_err .LE. cfg%EPS**2 )
311  ENDIF
312 !! COMPAD-DCO original code
313 !! FINISH = FINISH .AND. (DRV_ERR .LE. CFG%EPS**2 )
314 !#if defined COMPAD_DCO_T1S || COMPAD_DCO_T1V
315 ! WRITE(LU,*) ' CG CONVTEST',CNT,M,FINISH,RMRM,' :: ',
316 ! & SQRT(DRV_ERR),(DRV_ERR.LE.CFG%EPS**2), SQRT(SUM(DRV1**2)),
317 ! & SQRT(SUM(DRV0**2))
318 !#endif
319 #endif
320  IF ( finish ) GO TO 900
321 !
322 !-----------------------------------------------------------------------
323 ! PRECONDITIONING : SOLVES C G = R
324 !-----------------------------------------------------------------------
325 !
326  IF(prec) THEN
327 !
328 ! SOLVES C G = R
329  IF(crout.OR.gseb.OR.prebe) THEN
330  IF(ncsize.GT.1) THEN
331  WRITE(lu,*) 'NO CROUT PRECONDITIONNING IN PARALLEL'
332  CALL plante(1)
333  stop
334  ENDIF
335  CALL downup( g, aux , r , 'D' , mesh )
336  ELSEIF(pre3d) THEN
337  CALL cpstvc(r%ADR(1)%P,g%ADR(1)%P)
338  CALL trid3d(aux%X%R,g%ADR(1)%P%R,r%ADR(1)%P%R,
339  & mesh%NPOIN,bief_nbpts(11,mesh))
340  ENDIF
341 ! COMPUTES RMGM AND RM1GM1
342  rm1gm1 = sto1
343  rmgm = p_dots(r,g,mesh)
344  sto1=rmgm
345 !
346  ENDIF
347 !
348 !-----------------------------------------------------------------------
349 ! COMPUTES D BY RECURRENCE:
350 !-----------------------------------------------------------------------
351 !
352  beta = rmgm / rm1gm1
353 ! OPTIMISED EQUIVALENT OF THE 2 OS CALLS:
354  CALL os( 'X=Y+CZ ' , x=d , y=g , z=d , c=beta )
355 !
356 !-----------------------------------------------------------------------
357 ! PRECONDITIONING :
358 !-----------------------------------------------------------------------
359 !
360  IF(prec) THEN
361 ! COMPUTES RMDM
362  rmdm=p_dots(r,d,mesh)
363  ENDIF
364 !
365 !-----------------------------------------------------------------------
366 ! COMPUTES A D :
367 !-----------------------------------------------------------------------
368 !
369  CALL matrbl( 'X=AY ',ad,a,d,c,mesh)
370 !
371 !-----------------------------------------------------------------------
372 ! COMPUTES RO
373 !-----------------------------------------------------------------------
374 !
375  dad = p_dots(d,ad,mesh)
376  ro = rmdm/dad
377 !
378 ! COMPUTES X(M) = X(M-1) - RO * D
379 !
380  CALL os('X=X+CY ',x=x,y=d,c=-ro)
381 !
382 !-----------------------------------------------------------------------
383 #if defined COMPAD_DCO_T1S || COMPAD_DCO_T1V
384 ! TAKE TANGENT OF X1 IF WE ARE IN DCO_T1S MODE
385 ! AND STORE TANGENT OF FORMER X
386  drv0 = drv1
387 ! STORE TANGENT OF NEW X
388 # if defined COMPAD_DCO_T1S
389  CALL dco_t1s_get( x%ADR(1)%P%R, drv1, 1 )
390 # endif
391 # if defined COMPAD_DCO_T1V
392  CALL dco_t1v_get( x%ADR(1)%P%R, drv1, 1, 1 )
393 # endif
394 #endif
395 !-----------------------------------------------------------------------
396 !
397  IF(m.LT.cfg%NITMAX) GO TO 2
398 !
399 !-----------------------------------------------------------------------
400 !
401 ! IF(INFOGR) THEN
402  testl = sqrt( rmrm / xl )
403  IF (relat) THEN
404  WRITE(lu,104) m,testl
405  ELSE
406  WRITE(lu,204) m,testl
407  ENDIF
408 ! ENDIF
409  GO TO 1000
410 !
411 !-----------------------------------------------------------------------
412 !
413 900 CONTINUE
414 !
415  IF(infogr) THEN
416  testl = sqrt( rmrm / xl )
417  IF (relat) THEN
418  WRITE(lu,102) m,testl
419  ELSE
420  WRITE(lu,202) m,testl
421  ENDIF
422  ENDIF
423 !
424 1000 CONTINUE
425 !
426 !-----------------------------------------------------------------------
427 !
428 #if defined COMPAD_DCO_T1S || COMPAD_DCO_T1V
429 ! WRITE(LU,*) ' CG_END CONVTEST',
430 ! & CNT,M,FINISH,RMRM,' :: ',
431 ! & SQRT(DRV_ERR),(DRV_ERR.LE.CFG%EPS**2), SQRT(SUM(DRV1**2))
432 #endif
433 !
434 !-----------------------------------------------------------------------
435 !
436  RETURN
437 !
438 !-----------------------------------------------------------------------
439 !
440 ! FORMATS
441 !
442 102 FORMAT(1x,'GRACJG (BIEF) : ',
443  & 1i8,' ITERATIONS, RELATIVE PRECISION:',g16.7)
444 202 FORMAT(1x,'GRACJG (BIEF) : ',
445  & 1i8,' ITERATIONS, ABSOLUTE PRECISION:',g16.7)
446 104 FORMAT(1x,'GRACJG (BIEF) : EXCEEDING MAXIMUM ITERATIONS:',
447  & 1i8,' RELATIVE PRECISION:',g16.7)
448 106 FORMAT(1x,'GRACJG (BIEF) : ',
449  & ' SOLUTION X=0 BECAUSE L2-NORM OF B VERY SMALL:',g16.7)
450 204 FORMAT(1x,'GRACJG (BIEF) : EXCEEDING MAXIMUM ITERATIONS:',
451  & 1i8,' ABSOLUTE PRECISION:',g16.7)
452 !
453 !-----------------------------------------------------------------------
454 !
455  END
456 
integer function bief_nbpts(IELM, MESH)
Definition: bief_nbpts.f:7
subroutine trid3d(XAUX, X, B, NPOIN, NPOIN2)
Definition: trid3d.f:7
subroutine downup(X, A, B, DITR, MESH)
Definition: downup.f:7
subroutine gracjg(X, A, B, MESH, D, AD, G, R, CFG, INFOGR, AUX)
Definition: gracjg.F:7
subroutine cpstvc(X, Y)
Definition: cpstvc.f:7
subroutine os(OP, X, Y, Z, C, IOPT, INFINI, ZERO)
Definition: os.f:7
subroutine matrbl(OP, X, A, Y, C, MESH)
Definition: matrbl.f:7
double precision function p_dots(X, Y, MESH)
Definition: p_dots.f:7
Definition: bief.f:3