The TELEMAC-MASCARET system  trunk
precd4.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE precd4
3 ! *****************
4 !
5  &(x1,x2,a11,a12,a21,a22,
6  & b1,b2,d1,d2,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 4-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 diagonals 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 !| A12 |<->| TERM (1,2) OF MATRIX
44 !| A21 |<->| TERM (2,1) OF MATRIX
45 !| A22 |<->| TERM (2,2) OF MATRIX
46 !| B1 |<->| FIRST RIGHT-HAND SIDE
47 !| B2 |<->| SECOND RIGHT-HAND SIDE
48 !| D1 |<--| DIAGONAL MATRIX
49 !| D2 |<--| DIAGONAL MATRIX
50 !| DIADON |-->| .TRUE. : DIAGONALS ARE GIVEN
51 !| MESH |-->| MESH STRUCTURE
52 !| PRECON |-->| CHOICE OF PRECONDITIONING
53 !| PREXSM |-->| .TRUE. : PRECONDITIONING X1,X2 AND B1,B2
54 !| X1 |<->| FIRST INITIAL GUESS
55 !| X2 |-->| SECOND INITIAL GUESS
56 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57 !
58  USE bief, ex_precd4 => precd4
59 !
61  IMPLICIT NONE
62 !
63 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 !
65  INTEGER, INTENT(IN) :: PRECON
66  LOGICAL, INTENT(IN) :: PREXSM,DIADON
67 !
68 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 !
70 ! VECTOR STRUCTURES
71 !
72  TYPE(bief_obj), INTENT(INOUT) :: X1,X2,B1,B2,D1,D2
73 !
74 !-----------------------------------------------------------------------
75 !
76 ! MATRIX STRUCTURES
77 !
78  TYPE(bief_obj), INTENT(INOUT) :: A11,A12,A21,A22
79 !
80 !-----------------------------------------------------------------------
81 !
82 ! MESH STRUCTURE
83 !
84  TYPE(bief_mesh), INTENT(INOUT) :: MESH
85 !
86 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
87 !
88  INTEGER I
89 !
90 !-----------------------------------------------------------------------
91 !
92 ! PREPARES THE DIAGONALS:
93 !
94  IF(.NOT.diadon) THEN
95 !
96 ! COPY
97 !
98  CALL os( 'X=Y ' , x=d1 , y=a11%D )
99  CALL os( 'X=Y ' , x=d2 , y=a22%D )
100 !
101 ! PARALLEL MODE: COMPLETE DIAGONAL BEFORE GOING FURTHER
102 !
103  IF(ncsize.GT.1) THEN
104  CALL parcom(d1,2,mesh)
105  CALL parcom(d2,2,mesh)
106  ENDIF
107 !
108 ! POSSIBLY ABSOLUTE VALUES
109 !
110  IF(precon.EQ.5) THEN
111  CALL os( 'X=ABS(Y)' , x=d1 , y=d1 )
112  CALL os( 'X=ABS(Y)' , x=d2 , y=d2 )
113  ENDIF
114 !
115 ! SQUARE ROOT
116 !
117  CALL os( 'X=SQR(Y)' , x=d1 , y=d1 )
118  CALL os( 'X=SQR(Y)' , x=d2 , y=d2 )
119 !
120 !-----------------------------------------------------------------------
121 ! -1
122 ! CHANGE OF VARIABLES (D1,D2 AND D3 ACTUALLY HOLD D1 ,...)
123 !
124  IF(prexsm) THEN
125  CALL os( 'X=XY ' , x=x1 , y=d1 )
126  CALL os( 'X=XY ' , x=x2 , y=d2 )
127  ENDIF
128 !
129 !-----------------------------------------------------------------------
130 !
131 ! COMPUTES THE INVERSE OF THE SQUARE ROOTS OF THE DIAGONALS
132 ! THIS GIVES BACK TRUE D1 AND D2 AND NOT D1 AND D2 INVERTED
133 !
134  CALL os('X=1/Y ', x=d1, y=d1, iopt=2,
135  & infini=1.d0, zero=1.d-10)
136  CALL os('X=1/Y ', x=d2, y=d2, iopt=2,
137  & infini=1.d0, zero=1.d-10)
138 !
139  ELSE
140 !
141 ! CASE WHERE D IS GIVEN, CHANGE OF VARIABLES
142 ! CHANGE OF VARIABLE (D1,D2 REALLY HOLD D1,D2)
143 !
144  IF(prexsm) THEN
145  CALL os('X=Y/Z ' , x=x1 , y=x1 , z=d1)
146  CALL os('X=Y/Z ' , x=x2 , y=x2 , z=d2)
147  ENDIF
148 !
149  ENDIF
150 !
151 !=======================================================================
152 ! PRECONDITIONING OF A11 :
153 !=======================================================================
154 !
155  CALL om('M=DMD ', m=a11, d=d1, mesh=mesh)
156 !
157 !=======================================================================
158 ! PRECONDITIONING OF A12 :
159 !=======================================================================
160 !
161  CALL om('M=DM ', m=a12, d=d1, mesh=mesh)
162  CALL om('M=MD ', m=a12, d=d2, mesh=mesh)
163 !
164 !=======================================================================
165 ! PRECONDITIONING OF A21 :
166 !=======================================================================
167 !
168  CALL om('M=DM ', m=a21, d=d2, mesh=mesh)
169  CALL om('M=MD ', m=a21, d=d1, mesh=mesh)
170 !
171 !=======================================================================
172 ! PRECONDITIONING OF A22 :
173 !=======================================================================
174 !
175  CALL om('M=DMD ', m=a22, d=d2, mesh=mesh)
176 !
177 !=======================================================================
178 !
179 ! CASES WHERE THE DIAGONALS ARE KNOWN
180 ! (VALID ONLY WITH ONE SINGLE DOMAIN)
181 !
182  IF(ncsize.LE.1.OR.nptir.EQ.0) THEN
183 !
184 ! IF PRECON = 2 OR 3
185  IF(2*(precon/2).EQ.precon.AND..NOT.diadon) THEN
186  a11%TYPDIA='I'
187  a22%TYPDIA='I'
188  ELSEIF(3*(precon/3).EQ.precon.AND..NOT.diadon) THEN
189  a11%TYPDIA='I'
190  a22%TYPDIA='I'
191  a12%TYPDIA='0'
192  a21%TYPDIA='0'
193  ENDIF
194 !
195  ELSE
196 !
197 ! CASE OF DIAGONAL=IDENTITY, BUT ONLY AFTER ASSEMBLING
198 !
199  IF((2*(precon/2).EQ.precon.OR.3*(precon/3).EQ.precon).AND.
200  & .NOT.diadon) THEN
201 ! HERE THE DIAGONAL IS REDONE WITH IFAC, SO THAT A MATRIX-VECTOR
202 ! PRODUCT WILL LEAD TO A SUM OF THE SAME NUMBERS (BUT POSSIBLY
203 ! NOT IN THE SAME ORDER). OTHERWISE IT IS NOT SURE THAT THE
204 ! ASSEMBLED DIAGONAL WOULD GIVE EXACT 1.D0.
205  DO i=1,a11%D%DIM1
206  a11%D%R(i)=mesh%IFAC%I(i)
207  ENDDO
208  DO i=1,a22%D%DIM1
209  a22%D%R(i)=mesh%IFAC%I(i)
210  ENDDO
211  ENDIF
212 !
213  ENDIF
214 !
215 !=======================================================================
216 !
217 ! PRECONDITIONING OF THE SECOND MEMBER
218 !
219  IF(prexsm) THEN
220  CALL os( 'X=XY ' , x=b1 , y=d1 )
221  CALL os( 'X=XY ' , x=b2 , y=d2 )
222  ENDIF
223 !
224 !=======================================================================
225 !
226  RETURN
227  END
228 
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
subroutine precd4(X1, X2, A11, A12, A21, A22, B1, B2, D1, D2, MESH, PRECON, PREXSM, DIADON)
Definition: precd4.f:8
Definition: bief.f:3