The TELEMAC-MASCARET system  trunk
equnor.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE equnor
3 ! *****************
4 !
5  &(x, a,b , mesh, d,ad,ag,g,r, cfg,infogr,aux)
6 !
7 !***********************************************************************
8 ! BIEF V6P1 21/08/2010
9 !***********************************************************************
10 !
11 !brief SOLVES THE LINEAR SYSTEM A X = B
12 !+ USING METHODS OF THE TYPE CONJUGATE GRADIENT.
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 (LNH)
36 !+ 24/04/97
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 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53 !| A |-->| MATRIX OF THE SYSTEM
54 !| AD |<->| WORK ARRAY: MATRICE A MULTIPLIED BY D.
55 !| AG |<->| WORK ARRAY: A MULTIPLIED BY DESCENT GRADIENT
56 !| AUX |-->| MATRIX FOR PRECONDITIONING.
57 !| B |-->| RIGHT-HAND SIDE OF THE SYSTEM
58 !| CFG |-->| STRUCTURE OF SOLVER CONFIGURATION
59 !| D |<->| WORK ARRAY: DIRECTION OF DESCENT.
60 !| G |<->| DESCENT GRADIENT.
61 !| INFOGR |-->| IF YES, PRINT A LOG.
62 !| MESH |-->| MESH STRUCTURE.
63 !| R |<->| RESIDUAL (MAY BE IN THE SAME MEMORY SPACE AS
64 !| | | GRADIENT DEPENDING ON CONDITIONING)
65 !| X |<--| INITIAL VALUE, THEN SOLUTION
66 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67 !
68  USE bief, ex_equnor => equnor
69 !
71  IMPLICIT NONE
72 !
73 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 !
75  TYPE(slvcfg), INTENT(INOUT) :: CFG
76  TYPE(bief_obj), INTENT(INOUT) :: B
77  TYPE(bief_obj), INTENT(INOUT) :: D,AD,G,AG,R,X
78  TYPE(bief_mesh), INTENT(INOUT) :: MESH
79  TYPE(bief_obj), INTENT(IN) :: A
80  TYPE(bief_obj), INTENT(INOUT) :: AUX
81  LOGICAL, INTENT(IN) :: INFOGR
82 !
83 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84 !
85  INTEGER M
86 !
87  DOUBLE PRECISION XL,RMRM,TESTL
88  DOUBLE PRECISION BETA,ADAD,RO
89  DOUBLE PRECISION TGMTGM,TG1TG1,C
90 !
91  LOGICAL RELAT,PREC,CROUT,GSEB
92 !
93 !-----------------------------------------------------------------------
94 !
95  INTRINSIC sqrt
96 !
97 !-----------------------------------------------------------------------
98 !
99 ! INITIALISES
100 !
101  crout =.false.
102  IF(7*(cfg%PRECON/7).EQ.cfg%PRECON) crout=.true.
103  gseb=.false.
104  IF(11*(cfg%PRECON/11).EQ.cfg%PRECON) gseb=.true.
105  prec=.false.
106  IF(crout.OR.gseb.OR.13*(cfg%PRECON/13).EQ.cfg%PRECON) prec=.true.
107 !
108 !-----------------------------------------------------------------------
109 ! INITIALISES
110 !-----------------------------------------------------------------------
111 !
112  m = 0
113 !
114 ! NORMALISES THE SECOND MEMBER TO COMPUTE THE RELATIVE PRECISION:
115 !
116  xl = p_dots(b,b,mesh)
117 !
118  IF(xl.LT.1.d0) THEN
119  xl = 1.d0
120  relat = .false.
121  ELSE
122  relat = .true.
123  ENDIF
124 !
125 ! COMPUTES THE INITIAL RESIDUAL AND POSSIBLY EXITS:
126 !
127  CALL matrbl( 'X=AY ',r,a,x, c,mesh)
128 !
129  CALL os('X=X-Y ', x=r, y=b)
130  rmrm = p_dots(r,r,mesh)
131 !
132  IF (rmrm.LT.cfg%EPS**2*xl) GO TO 900
133 !
134 !-----------------------------------------------------------------------
135 ! PRECONDITIONING :
136 !-----------------------------------------------------------------------
137 !
138  IF(prec) THEN
139 !
140 ! COMPUTES C G0 = R
141  CALL downup(g, aux , r , 'D' , mesh)
142 !
143 ! C IS HERE CONSIDERED SYMMETRICAL,
144 ! SHOULD OTHERWISE SOLVE TC GPRIM = G
145 !
146 ! T -1
147 ! C G IS PUT IN B
148 !
149  CALL downup(b , aux , g , 'T' , mesh)
150 !
151  ENDIF
152 !
153 !-----------------------------------------------------------------------
154 ! COMPUTES THE DIRECTION OF INITIAL DESCENT:
155 !-----------------------------------------------------------------------
156 !
157  IF(prec) THEN
158  CALL matrbl( 'X=TAY ',d,a,b, c,mesh)
159  ELSE
160  CALL matrbl( 'X=TAY ',d,a,g, c,mesh)
161  ENDIF
162 !
163  tgmtgm = p_dots(d,d,mesh)
164 !
165 !-----------------------------------------------------------------------
166 ! COMPUTES THE INITIAL PRODUCT A D:
167 !-----------------------------------------------------------------------
168 !
169  CALL matrbl('X=AY ',ad,a,d,c,mesh)
170 !
171 !-----------------------------------------------------------------------
172 !
173  IF(prec) THEN
174 !
175 ! COMPUTES C DPRIM = AD (DPRIM PUT IN AG)
176  CALL downup(ag, aux , ad , 'D' , mesh)
177 !
178  ENDIF
179 !
180 !-----------------------------------------------------------------------
181 ! COMPUTES INITIAL RO :
182 !-----------------------------------------------------------------------
183 !
184  IF(prec) THEN
185  adad = p_dots(ag,ag,mesh)
186  ELSE
187  adad = p_dots(ad,ad,mesh)
188  ENDIF
189  ro = tgmtgm/adad
190 !
191 !-----------------------------------------------------------------------
192 !
193 ! COMPUTES X1 = X0 - RO * D
194 !
195  CALL os('X=X+CY ', x=x, y=d, c=-ro)
196 !
197 !-----------------------------------------------------------------------
198 ! ITERATIONS LOOP:
199 !-----------------------------------------------------------------------
200 !
201 2 m = m + 1
202 !
203 !-----------------------------------------------------------------------
204 ! COMPUTES THE RESIDUAL : R(M) = R(M-1) - RO(M-1) A D(M-1)
205 !-----------------------------------------------------------------------
206 !
207  CALL os('X=X+CY ', x=r, y=ad, c=-ro)
208 !
209 ! SOME VALUES WILL CHANGE IN CASE OF PRECONDITIONING
210 !
211  rmrm = p_dots(r,r,mesh)
212 !
213 ! CHECKS END :
214 !
215  IF (rmrm.LE.xl*cfg%EPS**2) GO TO 900
216 !
217 !-----------------------------------------------------------------------
218 ! PRECONDITIONING : SOLVES C G = R
219 !-----------------------------------------------------------------------
220 !
221  IF(prec) THEN
222 !
223 ! UPDATES G BY RECURRENCE (IN AG: DPRIM)
224  CALL os('X=X+CY ', x=g, y=ag, c=-ro)
225 !
226  CALL downup(b , aux , g , 'T' , mesh)
227 !
228  ENDIF
229 !
230 !-----------------------------------------------------------------------
231 ! COMPUTES D BY RECURRENCE:
232 !-----------------------------------------------------------------------
233 !
234  IF(prec) THEN
235 ! T T -1 T -1
236 ! AD IS HERE A C G B IS C G
237  CALL matrbl( 'X=TAY ',ad,a,b, c,mesh)
238  ELSE
239 ! AD IS HERE TAG
240  CALL matrbl( 'X=TAY ',ad,a,g, c,mesh)
241  ENDIF
242 !
243  tg1tg1 = tgmtgm
244  tgmtgm = p_dots(ad,ad,mesh)
245  beta = tgmtgm / tg1tg1
246 !
247  CALL os('X=CX ', x=d, c=beta)
248 !
249 ! AD IS HERE TAG
250  CALL os('X=X+Y ', x=d, y=ad)
251 !
252 !-----------------------------------------------------------------------
253 ! COMPUTES A D :
254 !-----------------------------------------------------------------------
255 !
256  CALL matrbl( 'X=AY ',ad,a,d, c,mesh)
257 !
258  IF(prec) THEN
259 !
260 ! COMPUTES C DPRIM = AD (DPRIM PUT IN AG)
261  CALL downup(ag , aux , ad , 'D' , mesh)
262 !
263  ENDIF
264 !
265 !-----------------------------------------------------------------------
266 ! COMPUTES RO
267 !-----------------------------------------------------------------------
268 !
269  IF(prec) THEN
270  adad = p_dots(ag,ag,mesh)
271  ELSE
272  adad = p_dots(ad,ad,mesh)
273  ENDIF
274  ro = tgmtgm/adad
275 !
276 ! COMPUTES X(M) = X(M-1) - RO * D
277 !
278  CALL os('X=X+CY ', x=x, y=d, c=-ro)
279 !
280  IF(m.LT.cfg%NITMAX) GO TO 2
281 !
282 !-----------------------------------------------------------------------
283 !
284 ! IF(INFOGR) THEN
285  testl = sqrt( rmrm / xl )
286  IF (relat) THEN
287  WRITE(lu,104) m,testl
288  ELSE
289  WRITE(lu,204) m,testl
290  ENDIF
291 ! ENDIF
292  GO TO 1000
293 !
294 !-----------------------------------------------------------------------
295 !
296 900 CONTINUE
297 !
298  IF(infogr) THEN
299  testl = sqrt( rmrm / xl )
300  IF (relat) THEN
301  WRITE(lu,102) m,testl
302  ELSE
303  WRITE(lu,202) m,testl
304  ENDIF
305  ENDIF
306 !
307 1000 RETURN
308 !
309 !-----------------------------------------------------------------------
310 !
311 ! FORMATS
312 !
313 102 FORMAT(1x,'EQUNOR (BIEF) : ',
314  & 1i8,' ITERATIONS, RELATIVE PRECISION:',g16.7)
315 202 FORMAT(1x,'EQUNOR (BIEF) : ',
316  & 1i8,' ITERATIONS, ABSOLUTE PRECISION:',g16.7)
317 104 FORMAT(1x,'EQUNOR (BIEF) : EXCEEDING MAXIMUM ITERATIONS:',
318  & 1i8,' RELATIVE PRECISION:',g16.7)
319 204 FORMAT(1x,'EQUNOR (BIEF) : EXCEEDING MAXIMUM ITERATIONS:',
320  & 1i8,' ABSOLUTE PRECISON:',g16.7)
321 !
322 !-----------------------------------------------------------------------
323 !
324  END
subroutine downup(X, A, B, DITR, MESH)
Definition: downup.f:7
subroutine os(OP, X, Y, Z, C, IOPT, INFINI, ZERO)
Definition: os.f:7
subroutine equnor(X, A, B, MESH, D, AD, AG, G, R, CFG, INFOGR, AUX)
Definition: equnor.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