The TELEMAC-MASCARET system  trunk
precd9.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE precd9
3 ! *****************
4 !
5  &(x1,x2,x3,a11,a12,a13,a21,a22,a23,a31,a32,a33,
6  & b1,b2,b3,d1,d2,d3,mesh,precon,prexsm,diadon)
7 !
8 !***********************************************************************
9 ! BIEF V7P1
10 !***********************************************************************
11 !
12 !brief DIAGONAL PRECONDITIONING OF A SYSTEM A X = B
13 !+ (SEE EXPLANATIONS IN PRECDT).
14 !+
15 !+ A IS A 9-MATRIX BLOCK HERE.
16 !
17 !history J-M HERVOUET (LNHE)
18 !+ 06/07/2009
19 !+ V5P0
20 !+ First version (of the header...)
21 !
22 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
23 !+ 13/07/2010
24 !+ V6P0
25 !+ Translation of French comments within the FORTRAN sources into
26 !+ English comments
27 !
28 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
29 !+ 21/08/2010
30 !+ V6P0
31 !+ Creation of DOXYGEN tags for automated documentation and
32 !+ cross-referencing of the FORTRAN sources
33 !
34 !history J-M HERVOUET (LNHE)
35 !+ 08/12/2015
36 !+ V7P1
37 !+ Rebuilding the diagonal with MESH%IFAC in parallel in case of
38 !+ diagonal preconditioning and DIADON=FALSE.
39 !+ Correction of a bug in parallel with preconditioning 5.
40 !
41 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42 !| A11 |<->| TERM (1,1) OF MATRIX
43 !| ... |<->| ...
44 !| A33 |<->| TERM (3,3) OF MATRIX
45 !| B1 |<->| FIRST RIGHT-HAND SIDE
46 !| B2 |<->| SECOND RIGHT-HAND SIDE
47 !| B3 |<->| THIRD RIGHT-HAND SIDE
48 !| D1 |<--| DIAGONAL MATRIX
49 !| D2 |<--| DIAGONAL MATRIX
50 !| D3 |<--| DIAGONAL MATRIX
51 !| DIADON |-->| .TRUE. : DIAGONALS ARE GIVEN
52 !| MESH |-->| MESH STRUCTURE
53 !| PRECON |-->| CHOICE OF PRECONDITIONING
54 !| PREXSM |-->| .TRUE. : PRECONDITIONING X1,X2 AND B1,B2
55 !| X1 |<->| FIRST INITIAL GUESS
56 !| X2 |-->| SECOND INITIAL GUESS
57 !| X3 |-->| THIRD INITIAL GUESS
58 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59 !
60  USE bief, ex_precd9 => precd9
61 !
63  IMPLICIT NONE
64 !
65 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 !
67  INTEGER, INTENT(IN) :: PRECON
68  LOGICAL, INTENT(IN) :: PREXSM,DIADON
69 !
70 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 !
72 ! VECTOR STRUCTURES
73 !
74  TYPE(bief_obj), INTENT(INOUT) :: X1,X2,X3,B1,B2,B3,D1,D2,D3
75 !
76 !-----------------------------------------------------------------------
77 !
78 ! MATRIX STRUCTURES
79 !
80  TYPE(bief_obj), INTENT(INOUT) :: A11,A12,A13,A21
81  TYPE(bief_obj), INTENT(INOUT) :: A22,A23,A31,A32,A33
82 !
83 !-----------------------------------------------------------------------
84 !
85 ! MESH STRUCTURE
86 !
87  TYPE(bief_mesh), INTENT(INOUT) :: MESH
88 !
89 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90 !
91  INTEGER I
92 !
93 !-----------------------------------------------------------------------
94 !
95 ! PREPARES THE DIAGONALS:
96 !
97  IF(.NOT.diadon) THEN
98 !
99 ! COPY
100 !
101  CALL os( 'X=Y ' , x=d1 , y=a11%D )
102  CALL os( 'X=Y ' , x=d2 , y=a22%D )
103  CALL os( 'X=Y ' , x=d3 , y=a33%D )
104 !
105 ! PARALLEL MODE: COMPLETE DIAGONAL BEFORE GOING FURTHER
106 !
107  IF(ncsize.GT.1) THEN
108  CALL parcom(d1,2,mesh)
109  CALL parcom(d2,2,mesh)
110  CALL parcom(d3,2,mesh)
111  ENDIF
112 !
113 ! POSSIBLY ABSOLUTE VALUES
114 !
115  IF(precon.EQ.5) THEN
116  CALL os( 'X=ABS(Y)' , x=d1 , y=d1 )
117  CALL os( 'X=ABS(Y)' , x=d2 , y=d2 )
118  CALL os( 'X=ABS(Y)' , x=d3 , y=d3 )
119  ENDIF
120 !
121 ! SQUARE ROOTS
122 !
123  CALL os( 'X=SQR(Y)' , x=d1 , y=d1 )
124  CALL os( 'X=SQR(Y)' , x=d2 , y=d2 )
125  CALL os( 'X=SQR(Y)' , x=d3 , y=d3 )
126 !
127 !-----------------------------------------------------------------------
128 ! -1
129 ! CHANGE OF VARIABLES (D1,D2 AND D3 ACTUALLY HOLD D1 ,...)
130 !
131  IF(prexsm) THEN
132  CALL os( 'X=XY ' , x=x1 , y=d1 )
133  CALL os( 'X=XY ' , x=x2 , y=d2 )
134  CALL os( 'X=XY ' , x=x3 , y=d3 )
135  ENDIF
136 !
137 !-----------------------------------------------------------------------
138 !
139 ! COMPUTES THE INVERSE OF THE SQUARE ROOTS OF THE DIAGONALS
140 ! THIS GIVES BACK TRUE D1,D2,D3 AND NOT D1,D2,D3 INVERTED
141 !
142  CALL os( 'X=1/Y ', x=d1, y=d1, iopt=2,
143  & infini=1.d0, zero=1.d-10)
144  CALL os( 'X=1/Y ', x=d2, y=d2, iopt=2,
145  & infini=1.d0, zero=1.d-10)
146  CALL os( 'X=1/Y ', x=d3, y=d3, iopt=2,
147  & infini=1.d0, zero=1.d-10)
148 !
149  ELSE
150 !
151 ! CASE WHERE D1,D2,D3 ARE GIVEN, CHANGE OF VARIABLES
152 ! CHANGE OF VARIABLE (D1,D2,D3 REALLY HOLD D1,D2,D3)
153 !
154  IF(prexsm) THEN
155  CALL os( 'X=Y/Z ' , x=x1 , y=x1 , z=d1 )
156  CALL os( 'X=Y/Z ' , x=x2 , y=x2 , z=d2 )
157  CALL os( 'X=Y/Z ' , x=x3 , y=x3 , z=d3 )
158  ENDIF
159 !
160  ENDIF
161 !
162 !=======================================================================
163 ! PRECONDITIONING OF A11 :
164 !=======================================================================
165 !
166  CALL om('M=DMD ', m=a11, d=d1, mesh=mesh)
167 !
168 !=======================================================================
169 ! PRECONDITIONING OF A12 :
170 !=======================================================================
171 !
172  CALL om('M=DM ', m=a12, d=d1, mesh=mesh)
173  CALL om('M=MD ', m=a12, d=d2, mesh=mesh)
174 !
175 !=======================================================================
176 ! PRECONDITIONING OF A13 :
177 !=======================================================================
178 !
179  CALL om('M=DM ', m=a13, d=d1, mesh=mesh)
180  CALL om('M=MD ', m=a13, d=d3, mesh=mesh)
181 !
182 !=======================================================================
183 ! PRECONDITIONING OF A21 :
184 !=======================================================================
185 !
186  CALL om('M=DM ', m=a21, d=d2, mesh=mesh)
187  CALL om('M=MD ', m=a21, d=d1, mesh=mesh)
188 !
189 !=======================================================================
190 ! PRECONDITIONING OF A22 :
191 !=======================================================================
192 !
193  CALL om('M=DMD ', m=a22, d=d2, mesh=mesh)
194 !
195 !=======================================================================
196 ! PRECONDITIONING OF A23 :
197 !=======================================================================
198 !
199  CALL om('M=DM ', m=a23, d=d2, mesh=mesh)
200  CALL om('M=MD ', m=a23, d=d3, mesh=mesh)
201 !
202 !=======================================================================
203 ! PRECONDITIONING OF A31 :
204 !=======================================================================
205 !
206  CALL om('M=DM ', m=a31, d=d3, mesh=mesh)
207  CALL om('M=MD ', m=a31, d=d1, mesh=mesh)
208 !
209 !=======================================================================
210 ! PRECONDITIONING OF A32 :
211 !=======================================================================
212 !
213  CALL om('M=DM ', m=a32, d=d3, mesh=mesh)
214  CALL om('M=MD ', m=a32, d=d2, mesh=mesh)
215 !
216 !=======================================================================
217 ! PRECONDITIONING OF A33 :
218 !=======================================================================
219 !
220  CALL om('M=DMD ', m=a33, d=d3, mesh=mesh)
221 !
222 !=======================================================================
223 !
224 ! CASES WHERE THE DIAGONALS ARE KNOWN
225 ! (VALID ONLY WITH ONE SINGLE DOMAIN)
226 !
227  IF(ncsize.LE.1.OR.nptir.EQ.0) THEN
228 !
229 ! IF PRECON = 2 OR 3
230  IF(2*(precon/2).EQ.precon.AND..NOT.diadon) THEN
231  a11%TYPDIA='I'
232  a22%TYPDIA='I'
233  a33%TYPDIA='I'
234  ELSEIF(3*(precon/3).EQ.precon.AND..NOT.diadon) THEN
235  a11%TYPDIA='I'
236  a22%TYPDIA='I'
237  a33%TYPDIA='I'
238  a12%TYPDIA='0'
239  a13%TYPDIA='0'
240  a21%TYPDIA='0'
241  a23%TYPDIA='0'
242  a31%TYPDIA='0'
243  a32%TYPDIA='0'
244  ENDIF
245 !
246  ELSE
247 !
248 ! CASE OF DIAGONAL=IDENTITY, BUT ONLY AFTER ASSEMBLING
249 !
250  IF((2*(precon/2).EQ.precon.OR.3*(precon/3).EQ.precon).AND.
251  & .NOT.diadon) THEN
252 ! HERE THE DIAGONAL IS REDONE WITH IFAC, SO THAT A MATRIX-VECTOR
253 ! PRODUCT WILL LEAD TO A SUM OF THE SAME NUMBERS (BUT POSSIBLY
254 ! NOT IN THE SAME ORDER). OTHERWISE IT IS NOT SURE THAT THE
255 ! ASSEMBLED DIAGONAL WOULD GIVE EXACT 1.D0.
256  DO i=1,a11%D%DIM1
257  a11%D%R(i)=mesh%IFAC%I(i)
258  ENDDO
259  DO i=1,a22%D%DIM1
260  a22%D%R(i)=mesh%IFAC%I(i)
261  ENDDO
262  DO i=1,a33%D%DIM1
263  a33%D%R(i)=mesh%IFAC%I(i)
264  ENDDO
265  ENDIF
266 !
267  ENDIF
268 !
269 !=======================================================================
270 !
271 ! PRECONDITIONING OF THE SECOND MEMBER
272 !
273  IF(prexsm) THEN
274  CALL os( 'X=XY ' , x=b1 , y=d1 )
275  CALL os( 'X=XY ' , x=b2 , y=d2 )
276  CALL os( 'X=XY ' , x=b3 , y=d3 )
277  ENDIF
278 !
279 !=======================================================================
280 !
281  RETURN
282  END
283 
subroutine precd9(X1, X2, X3, A11, A12, A13, A21, A22, A23, A31, A32, A33, B1, B2, B3, D1, D2, D3, MESH, PRECON, PREXSM, DIADON)
Definition: precd9.f:8
subroutine om(OP, M, N, D, C, MESH)
Definition: om.f:7
subroutine os(OP, X, Y, Z, C, IOPT, INFINI, ZERO)
Definition: os.f:7
subroutine parcom(X, ICOM, MESH)
Definition: parcom.f:7
Definition: bief.f:3