The TELEMAC-MASCARET system  trunk
rescjg.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE rescjg
3 ! *****************
4 !
5  &(x, a,b , mesh,d,ad,ag,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 RESIDUAL METHOD.
13 !code
14 !+-----------------------------------------------------------------------
15 !+ PRECONDITIONING
16 !+-----------------------------------------------------------------------
17 !+ 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 (LNHE)
36 !+ 27/02/06
37 !+ V5P6
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 !| AG |<->| WORK ARRAY: MATRICE A MULTIPLIED BY G.
62 !| AUX |-->| MATRIX FOR PRECONDITIONING.
63 !| B |-->| RIGHT-HAND SIDE OF THE SYSTEM
64 !| CFG |-->| STRUCTURE OF SOLVER CONFIGURATION
65 !| D |<->| WORK ARRAY: DIRECTION OF DESCENT.
66 !| G |<->| DESCENT GRADIENT.
67 !| INFOGR |-->| IF YES, PRINT A LOG.
68 !| MESH |-->| MESH STRUCTURE.
69 !| R |<->| RESIDUAL (MAY BE IN THE SAME MEMORY SPACE AS
70 !| | | GRADIENT DEPENDING ON CONDITIONING)
71 !| X |<->| INITIAL VALUE, THEN SOLUTION
72 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73 !
74  USE bief, ex_rescjg => rescjg
75 !
77  IMPLICIT NONE
78 !
79 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80 !
81  LOGICAL, INTENT(IN) :: INFOGR
82 !
83 ! STRUCTURES
84 !
85  TYPE(bief_obj), INTENT(INOUT) :: D,AD,G,AG,R,X,B
86  TYPE(slvcfg) , INTENT(INOUT) :: CFG
87 !
88 ! MESH STRUCTURE
89 !
90  TYPE(bief_mesh), INTENT(INOUT) :: MESH
91 !
92 ! MATRIX STRUCTURE
93 !
94  TYPE(bief_obj), INTENT(IN) :: A
95  TYPE(bief_obj), INTENT(INOUT) :: AUX
96 !
97 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98 !
99  INTEGER M
100 !
101  DOUBLE PRECISION XL,RMRM,TESTL,GAD
102  DOUBLE PRECISION AGAD,BETA,ADAD,RO,DAD
103  DOUBLE PRECISION C
104 !
105  LOGICAL RELAT,PREC,CROUT,GSEB,PREBE,PRE3D
106 !
107 !-----------------------------------------------------------------------
108 !
109  INTRINSIC sqrt
110 !
111 !-----------------------------------------------------------------------
112 !
113 ! INITIALISES
114 !
115  crout =.false.
116  IF(7*(cfg%PRECON/7).EQ.cfg%PRECON) crout=.true.
117  gseb=.false.
118  IF(11*(cfg%PRECON/11).EQ.cfg%PRECON) gseb=.true.
119  prebe=.false.
120  IF(13*(cfg%PRECON/13).EQ.cfg%PRECON) prebe=.true.
121  pre3d=.false.
122  IF(17*(cfg%PRECON/17).EQ.cfg%PRECON) pre3d=.true.
123  prec=.false.
124  IF(crout.OR.gseb.OR.prebe.OR.pre3d) prec=.true.
125 !
126 !-----------------------------------------------------------------------
127 ! INITIALISES
128 !-----------------------------------------------------------------------
129 !
130  m = 0
131 !
132 ! NORMALISES THE SECOND MEMBER TO COMPUTE THE RELATIVE PRECISION:
133 !
134  xl = p_dots(b,b,mesh)
135  IF (xl.LT.1.d0) THEN
136  xl = 1.d0
137  relat = .false.
138  ELSE
139  relat = .true.
140  ENDIF
141 !
142 ! COMPUTES THE INITIAL RESIDUAL AND POSSIBLY EXITS:
143 !
144  CALL matrbl( 'X=AY ',r,a,x, c,mesh)
145 !
146  CALL os('X=X-Y ', x=r, y=b)
147  rmrm = p_dots(r,r,mesh)
148 !
149  IF (rmrm.LT.cfg%EPS**2*xl) GO TO 900
150 !
151 !-----------------------------------------------------------------------
152 ! PRECONDITIONING :
153 !-----------------------------------------------------------------------
154 !
155  IF(prec) THEN
156 !
157 ! COMPUTES C G0 = R
158 !
159  IF(crout.OR.gseb.OR.prebe) THEN
160  IF(ncsize.GT.1) THEN
161  WRITE(lu,*) 'NO CROUT PRECONDITIONNING IN PARALLEL'
162  CALL plante(1)
163  stop
164  ENDIF
165  CALL downup(g, aux , r , 'D' , mesh)
166  ELSEIF(pre3d) THEN
167  CALL cpstvc(r%ADR(1)%P,g%ADR(1)%P)
168  CALL trid3d(aux%X%R,g%ADR(1)%P%R,r%ADR(1)%P%R,
169  & mesh%NPOIN,bief_nbpts(11,mesh))
170  ENDIF
171 !
172  ENDIF
173 !
174 !-----------------------------------------------------------------------
175 ! COMPUTES THE DIRECTION OF INITIAL DESCENT:
176 !-----------------------------------------------------------------------
177 !
178  CALL os('X=Y ', x=d, y=g)
179 !
180 !-----------------------------------------------------------------------
181 ! COMPUTES THE INITIAL PRODUCT A D :
182 !-----------------------------------------------------------------------
183 !
184  CALL matrbl( 'X=AY ',ad,a,d, c,mesh)
185 !
186 !-----------------------------------------------------------------------
187 !
188  IF(prec) THEN
189 !
190 ! COMPUTES C DPRIM = AD (DPRIM PUT IN B)
191 !
192  IF(crout.OR.gseb.OR.prebe) THEN
193  IF(ncsize.GT.1) THEN
194  WRITE(lu,*) 'NO CROUT PRECONDITIONNING IN PARALLEL'
195  CALL plante(1)
196  stop
197  ENDIF
198  CALL downup(b, aux , ad , 'D' , mesh)
199  ELSEIF(pre3d) THEN
200  CALL cpstvc(r%ADR(1)%P,g%ADR(1)%P)
201  CALL trid3d(aux%X%R,b%ADR(1)%P%R,ad%ADR(1)%P%R,
202  & mesh%NPOIN,bief_nbpts(11,mesh))
203  ENDIF
204 !
205  ENDIF
206 !
207 !-----------------------------------------------------------------------
208 ! COMPUTES INITIAL RO :
209 !-----------------------------------------------------------------------
210 !
211  dad = p_dots(d,ad,mesh)
212  IF(prec) THEN
213  adad = p_dots(ad,b,mesh)
214  ELSE
215  adad = p_dots(ad,ad,mesh)
216  ENDIF
217  ro = dad/adad
218 !
219 !-----------------------------------------------------------------------
220 !
221 ! COMPUTES X1 = X0 - RO * D
222 !
223  CALL os('X=X+CY ', x=x, y=d, c=-ro)
224 !
225 !-----------------------------------------------------------------------
226 ! ITERATIONS LOOP:
227 !-----------------------------------------------------------------------
228 !
229 2 m = m + 1
230 !
231 !-----------------------------------------------------------------------
232 ! COMPUTES THE RESIDUAL : R(M) = R(M-1) - RO(M-1) A D(M-1)
233 !-----------------------------------------------------------------------
234 !
235  CALL os('X=X+CY ', x=r, y=ad, c=-ro)
236 !
237 ! SOME VALUES WILL CHANGE IN CASE OF PRECONDITIONING
238 !
239  rmrm = p_dots(r,r,mesh)
240 !
241 ! CHECKS END:
242 !
243  IF (rmrm.LE.xl*cfg%EPS**2) GO TO 900
244 !
245 !-----------------------------------------------------------------------
246 ! PRECONDITIONING : SOLVES C G = R
247 !-----------------------------------------------------------------------
248 !
249  IF(prec) THEN
250 ! UPDATES G BY RECURRENCE (IN B: DPRIM)
251  CALL os('X=X+CY ', x=g, y=b, c=-ro)
252  ENDIF
253 !
254 !-----------------------------------------------------------------------
255 ! COMPUTES AG :
256 !-----------------------------------------------------------------------
257 !
258  CALL matrbl( 'X=AY ',ag,a,g, c,mesh)
259 !
260 !-----------------------------------------------------------------------
261 ! COMPUTES D BY RECURRENCE:
262 !-----------------------------------------------------------------------
263 !
264  IF(prec) THEN
265  agad = p_dots(ag,b,mesh)
266  ELSE
267  agad = p_dots(ag,ad,mesh)
268  ENDIF
269  beta = - agad / adad
270 !
271  CALL os('X=CX ', x=d, c=beta)
272  CALL os('X=X+Y ', x=d, y=g)
273 !
274 !-----------------------------------------------------------------------
275 ! COMPUTES A D :
276 !-----------------------------------------------------------------------
277 !
278  CALL os('X=CX ', x=ad, c=beta)
279  CALL os('X=X+Y ', x=ad, y=ag)
280 !
281  IF(prec) THEN
282 !
283 ! COMPUTES C DPRIM = AD (DPRIM PUT IN B)
284 !
285  IF(crout.OR.gseb.OR.prebe) THEN
286  IF(ncsize.GT.1) THEN
287  WRITE(lu,*) 'NO CROUT PRECONDITIONNING IN PARALLEL'
288  CALL plante(1)
289  stop
290  ENDIF
291  CALL downup(b , aux , ad , 'D' , mesh)
292  ELSEIF(pre3d) THEN
293  CALL trid3d(aux%X%R,b%ADR(1)%P%R,ad%ADR(1)%P%R,
294  & mesh%NPOIN,bief_nbpts(11,mesh))
295  ENDIF
296 !
297  ENDIF
298 !
299 !-----------------------------------------------------------------------
300 ! COMPUTES RO
301 !-----------------------------------------------------------------------
302 !
303  gad = p_dots(g,ad,mesh)
304  IF(prec) THEN
305  adad = p_dots(ad,b,mesh)
306  ELSE
307  adad = p_dots(ad,ad,mesh)
308  ENDIF
309  ro = gad/adad
310 !
311 ! COMPUTES X(M) = X(M-1) - RO * D
312 !
313  CALL os('X=X+CY ', x=x, y=d, c=-ro)
314 !
315  IF(m.LT.cfg%NITMAX) GO TO 2
316 !
317 !-----------------------------------------------------------------------
318 !
319  IF(infogr) THEN
320  testl = sqrt( rmrm / xl )
321  IF (relat) THEN
322  WRITE(lu,104) m,testl
323  ELSE
324  WRITE(lu,204) m,testl
325  ENDIF
326  ENDIF
327  GO TO 1000
328 !
329 !-----------------------------------------------------------------------
330 !
331 900 CONTINUE
332 !
333  IF(infogr) THEN
334  testl = sqrt( rmrm / xl )
335  IF (relat) THEN
336  WRITE(lu,102) m,testl
337  ELSE
338  WRITE(lu,202) m,testl
339  ENDIF
340  ENDIF
341 !
342 1000 RETURN
343 !
344 !-----------------------------------------------------------------------
345 !
346 ! FORMATS
347 !
348 102 FORMAT(1x,'RESCJG (BIEF) : ',
349  & 1i8,' ITERATIONS, RELATIVE PRECISION:',g16.7)
350 202 FORMAT(1x,'RESCJG (BIEF) : ',
351  & 1i8,' ITERATIONS, ABSOLUTE PRECISION:',g16.7)
352 104 FORMAT(1x,'RESCJG (BIEF) : EXCEEDING MAXIMUM ITERATIONS:',
353  & 1i8,' RELATIVE PRECISION:',g16.7)
354 204 FORMAT(1x,'RESCJG (BIEF) : EXCEEDING MAXIMUM ITERATIONS:',
355  & 1i8,' ABSOLUTE PRECISON:',g16.7)
356 !
357 !-----------------------------------------------------------------------
358 !
359  END
360 
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 rescjg(X, A, B, MESH, D, AD, AG, G, R, CFG, INFOGR, AUX)
Definition: rescjg.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