SFEMaNS  version 4.1 (work in progress)
Reference documentation for SFEMaNS
 All Classes Files Functions Variables Groups Pages
dir_nodes.f90
Go to the documentation of this file.
1 !
2 !Authors: Jean-Luc Guermond, Lugi Quartapelle, Copyright 1994
3 !
4 MODULE dir_nodes
5 
6 CONTAINS
7 
8  SUBROUTINE precond_mat(ia, aa, vect)
9  IMPLICIT NONE
10  INTEGER, DIMENSION(:), INTENT(IN) :: ia
11  REAL(KIND=8), DIMENSION(:), INTENT(INOUT) :: aa
12  REAL(KIND=8), DIMENSION(:), INTENT(OUT) :: vect
13  INTEGER :: ii,j
14  REAL(KIND=8) :: s
15 
16 
17  ! write(*,*) 'SIZE(ia)=',SIZE(ia)
18  ! write(*,*) 'SIZE(aa)=',SIZE(aa)
19  ! write(*,*) 'SIZE(vect)=',SIZE(vect)
20 
21  DO ii=1, SIZE(ia)-1 !pour toutes les lignes
22  s = 0.d0
23  DO j=ia(ii), ia(ii+1)-1
24  s = s + abs(aa(j))
25  !S = MAX(S,ABS(aa(j)))
26  !MODIF 16 MARS 2007
27  !S = 1.d0
28  !MODIF 16 MARS 2007
29  ENDDO
30  !WRITE(*,*) 'S= ', S
31  vect(ii) = 1.d0/s
32  DO j=ia(ii), ia(ii+1)-1
33  aa(j) = aa(j)/s
34  ENDDO
35  ENDDO
36 
37 
38  END SUBROUTINE precond_mat
39 
40 
41 
42 SUBROUTINE dirichlet_m (js, ia, ja, a0)
43 !=================================================
44 
45 ! Enforces Dirichlet boundary conditions
46 
47  IMPLICIT NONE
48  INTEGER, DIMENSION(:), INTENT(IN) :: js
49  INTEGER, DIMENSION(:), INTENT(IN) :: ia
50  INTEGER, DIMENSION(:), INTENT(IN) :: ja
51  REAL(KIND=8), DIMENSION(:), INTENT(INOUT) :: a0
52  INTEGER :: n, i, p
53 
54  DO n = 1, SIZE(js); i = js(n)
55 
56  DO p = ia(i), ia(i+1) - 1
57  IF (ja(p) == i) THEN
58  a0(p) = 1.d0
59 
60  ELSE
61  a0(p)=0.d0
62  END IF
63  END DO
64 
65  END DO
66 
67 END SUBROUTINE dirichlet_m
68 
69 SUBROUTINE dirichlet_rescale_m (js, ia, ja, alpha, a0)
70 !=================================================
71 
72 ! Enforces Dirichlet boundary conditions
73 
74  IMPLICIT NONE
75  INTEGER, DIMENSION(:), INTENT(IN) :: js
76  INTEGER, DIMENSION(:), INTENT(IN) :: ia
77  INTEGER, DIMENSION(:), INTENT(IN) :: ja
78  REAL(KIND=8), DIMENSION(:), INTENT(INOUT) :: a0
79  REAL(KIND=8), INTENT(IN) :: alpha
80 
81  INTEGER :: n, i, p
82 
83  DO n = 1, SIZE(js); i = js(n)
84  DO p = ia(i), ia(i+1) - 1
85  IF (ja(p) == i) THEN
86  a0(p) = alpha
87  ELSE
88  a0(p)=0.d0
89  END IF
90  END DO
91  END DO
92 
93 END SUBROUTINE dirichlet_rescale_m
94 
95 SUBROUTINE dirichlet_bloc_m (js_D, ia, ja, a0)
96 !=================================================
97 
98 ! Enforces Dirichlet boundary conditions
99 
100  USE dyn_line;
101  IMPLICIT NONE
102  TYPE(dyn_int_line), DIMENSION(:) :: js_d ! Dirichlet nodes
103  INTEGER, DIMENSION(:), INTENT(IN) :: ia
104  INTEGER, DIMENSION(:), INTENT(IN) :: ja
105  REAL(KIND=8), DIMENSION(:), INTENT(INOUT) :: a0
106 
107  INTEGER :: n, i, k, p, np
108 
109  np = (SIZE(ia) - 1)/SIZE(js_d)
110  DO k = 1, SIZE(js_d)
111  DO n = 1, SIZE(js_d(k)%DIL); i = js_d(k)%DIL(n) + (k-1)*np
112  DO p = ia(i), ia(i+1) - 1
113  IF (ja(p) == i) THEN
114  a0(p) = 1.d0
115  ELSE
116  a0(p)=0.d0
117  END IF
118  END DO
119  END DO
120  END DO
121 
122 END SUBROUTINE dirichlet_bloc_m
123 
124 SUBROUTINE dir_nodes_size(js, sides, Dir, j_D_size)
125 
126  IMPLICIT NONE
127 
128  INTEGER, DIMENSION(:,:), INTENT(IN) :: js
129  INTEGER, DIMENSION(:), INTENT(IN) :: sides
130  LOGICAL, DIMENSION(:), INTENT(IN) :: dir
131  INTEGER, INTENT(OUT) :: j_d_size
132 
133  INTEGER, DIMENSION(:), ALLOCATABLE :: j_all, j_dif
134  INTEGER :: nj, ms, ns
135 
136 ! count all nodes of the boundary elements which belong to
137 ! the sides where a Dirichlet boundary condition is prescribed
138 
139 ! If the same node belongs to different sides of the boundary
140 ! the algorithm takes it into account only once.
141 
142  nj = 0
143  DO ms = 1, SIZE(js, 2)
144  IF ( dir(sides(ms)) ) nj = nj + SIZE(js, 1)
145  ENDDO
146 
147  ALLOCATE (j_all(nj), j_dif(nj))
148 
149 ! collect all nodes of the boundary elements which belong to
150 ! the sides where a Dirichlet boundary condition is prescribed
151 
152  nj = 0
153  DO ms = 1, SIZE(js, 2)
154 
155  IF ( dir(sides(ms)) ) THEN
156 
157  DO ns = 1, SIZE(js, 1)
158  nj = nj + 1
159  j_all(nj) = js(ns, ms)
160  ENDDO
161 
162 !TEST***************! problem with version.1 of F90 on CRAY90
163 ! PRINT*, ' ms, j_all(ms), js', ms,j_all(ms),js(1,ms),js(2,ms)
164 !TEST***************
165  ENDIF
166 
167  ENDDO
168 
169 
170  CALL sort_diff(j_all, j_dif, j_d_size)
171 
172  DEALLOCATE (j_all, j_dif)
173 
174 CONTAINS
175 
176 SUBROUTINE sort_diff (a, a_d, n_a_d)
177 
178 ! sort in ascending order of the integer array a and generation
179 ! of the integer array a_d whose first n_a_d leading entries
180 ! contain different values in ascending order, while all the
181 ! remaining entries are set to zero
182 
183 ! sorting by Shell's method.
184 
185  IMPLICIT NONE
186 
187  INTEGER, DIMENSION(:), INTENT(INOUT) :: a
188  INTEGER, DIMENSION(:), INTENT(OUT) :: a_d
189  INTEGER, INTENT(OUT) :: n_a_d
190 
191  INTEGER :: n, na, inc, i, j, k, ia
192 
193  na = SIZE(a)
194 
195 ! sort phase
196 
197  IF (na == 0) THEN
198  n_a_d = 0
199  RETURN
200  ENDIF
201 
202  inc = 1
203  DO WHILE (inc <= na)
204  inc = inc * 3
205  inc = inc + 1
206  ENDDO
207 
208  DO WHILE (inc > 1)
209  inc = inc/3
210  DO i = inc + 1, na
211  ia = a(i)
212  j = i
213  DO WHILE (a(j-inc) > ia)
214  a(j) = a(j-inc)
215  j = j - inc
216  IF (j <= inc) EXIT
217  ENDDO
218  a(j) = ia
219  ENDDO
220  ENDDO
221 
222 ! compression phase
223 
224  n = 1
225  a_d(n) = a(1)
226  DO k = 2, na
227  IF (a(k) > a(k-1)) THEN
228  n = n + 1
229  a_d(n) = a(k)
230  ENDIF
231  ENDDO
232 
233  n_a_d = n
234 
235  a_d(n_a_d + 1 : na) = 0
236 
237 END SUBROUTINE sort_diff
238 
239 END SUBROUTINE dir_nodes_size
240 
241 
242 
243 SUBROUTINE dir_nodes_gen(js, sides, Dir, j_D)
244 
245  IMPLICIT NONE
246 
247  INTEGER, DIMENSION(:,:), INTENT(IN) :: js
248  INTEGER, DIMENSION(:), INTENT(IN) :: sides
249  LOGICAL, DIMENSION(:), INTENT(IN) :: dir
250  INTEGER, DIMENSION(:), INTENT(OUT) :: j_d
251 
252  INTEGER, DIMENSION(:), ALLOCATABLE :: j_all, j_dif
253  INTEGER :: nj, ms, ns, nj_dif
254 
255 ! count all nodes of the boundary elements which belong to
256 ! the sides where a Dirichlet boundary condition is prescribed
257 
258 ! If the same node belongs to different sides of the boundary
259 ! the algorithm takes it into account only once.
260 
261  nj = 0
262  DO ms = 1, SIZE(js, 2)
263  IF ( dir(sides(ms)) ) nj = nj + SIZE(js, 1)
264  ENDDO
265 
266  ALLOCATE (j_all(nj), j_dif(nj))
267 
268 ! collect all nodes of the boundary elements which belong to
269 ! the sides where a Dirichlet boundary condition is prescribed
270 
271  nj = 0
272  DO ms = 1, SIZE(js, 2)
273 
274  IF ( dir(sides(ms)) ) THEN
275 
276  DO ns = 1, SIZE(js, 1)
277  nj = nj + 1
278  j_all(nj) = js(ns, ms)
279  ENDDO
280 
281  ENDIF
282 
283  ENDDO
284 
285  CALL sort_diff(j_all, j_dif, nj_dif)
286 
287  j_d = j_dif(1:nj_dif)
288 
289  DEALLOCATE (j_all, j_dif)
290 
291 
292 CONTAINS
293 
294 SUBROUTINE sort_diff (a, a_d, n_a_d)
295 
296 ! sort in ascending order of the integer array a and generation
297 ! of the integer array a_d whose first n_a_d leading entries
298 ! contain different values in ascending order, while all the
299 ! remaining entries are set to zero
300 
301 ! sorting by Shell's method.
302 
303  IMPLICIT NONE
304 
305  INTEGER, DIMENSION(:), INTENT(INOUT) :: a
306  INTEGER, DIMENSION(:), INTENT(OUT) :: a_d
307  INTEGER, INTENT(OUT) :: n_a_d
308 
309  INTEGER :: n, na, inc, i, j, k, ia
310 
311  na = SIZE(a)
312 
313 ! sort phase
314 
315  IF (na == 0) THEN
316  n_a_d = 0
317  RETURN
318  ENDIF
319 
320  inc = 1
321  DO WHILE (inc <= na)
322  inc = inc * 3
323  inc = inc + 1
324  ENDDO
325 
326  DO WHILE (inc > 1)
327  inc = inc/3
328  DO i = inc + 1, na
329  ia = a(i)
330  j = i
331  DO WHILE (a(j-inc) > ia)
332  a(j) = a(j-inc)
333  j = j - inc
334  IF (j <= inc) EXIT
335  ENDDO
336  a(j) = ia
337  ENDDO
338  ENDDO
339 
340 ! compression phase
341 
342  n = 1
343  a_d(n) = a(1)
344  DO k = 2, na
345  IF (a(k) > a(k-1)) THEN
346  n = n + 1
347  a_d(n) = a(k)
348  ENDIF
349  ENDDO
350 
351  n_a_d = n
352 
353  a_d(n_a_d + 1 : na) = 0
354 
355 END SUBROUTINE sort_diff
356 
357 END SUBROUTINE dir_nodes_gen
358 
359 
360 SUBROUTINE dir_nodes_sides_gen(js, sides, Dir, j_D, s_D)
361 
362  IMPLICIT NONE
363 
364  INTEGER, DIMENSION(:,:), INTENT(IN) :: js
365  INTEGER, DIMENSION(:), INTENT(IN) :: sides
366  LOGICAL, DIMENSION(:), INTENT(IN) :: dir
367  INTEGER, DIMENSION(:), INTENT(OUT) :: j_d, s_d
368 
369  INTEGER, DIMENSION(:), ALLOCATABLE :: j_all, j_dif, s_all
370  INTEGER :: nj, ms, ns, nj_dif
371 
372 ! count all nodes of the boundary elements which belong to
373 ! the sides where a Dirichlet boundary condition is prescribed
374 
375 ! If the same node belongs to different sides of the boundary
376 ! the algorithm takes it into account only once.
377 
378  nj = 0
379  DO ms = 1, SIZE(js, 2)
380  IF ( dir(sides(ms)) ) nj = nj + SIZE(js, 1)
381  ENDDO
382 
383  ALLOCATE (j_all(nj), j_dif(nj))
384 
385 ! collect all nodes of the boundary elements which belong to
386 ! the sides where a Dirichlet boundary condition is prescribed
387 
388  nj = 0
389  DO ms = 1, SIZE(js, 2)
390 
391  IF ( dir(sides(ms)) ) THEN
392 
393  DO ns = 1, SIZE(js, 1)
394  nj = nj + 1
395  j_all(nj) = js(ns, ms)
396  ENDDO
397 
398  ENDIF
399 
400  ENDDO
401 
402  CALL sort_diff(j_all, j_dif, nj_dif)
403 
404  j_d = j_dif(1:nj_dif)
405 
406  nj = maxval(j_d)
407  ALLOCATE (s_all(nj))
408  nj = 0
409  DO ms = 1, SIZE(js, 2)
410 
411  IF ( dir(sides(ms)) ) THEN
412 
413  DO ns = 1, SIZE(js, 1)
414  nj = nj + 1
415  s_all(js(ns, ms)) = sides(ms)
416  ENDDO
417 
418  ENDIF
419 
420  ENDDO
421 
422  s_d = s_all(j_d(1:nj_dif))
423 
424  DEALLOCATE (j_all, j_dif, s_all)
425 
426 CONTAINS
427 
428 SUBROUTINE sort_diff (a, a_d, n_a_d)
429 
430 ! sort in ascending order of the integer array a and generation
431 ! of the integer array a_d whose first n_a_d leading entries
432 ! contain different values in ascending order, while all the
433 ! remaining entries are set to zero
434 
435 ! sorting by Shell's method.
436 
437  IMPLICIT NONE
438 
439  INTEGER, DIMENSION(:), INTENT(INOUT) :: a
440  INTEGER, DIMENSION(:), INTENT(OUT) :: a_d
441  INTEGER, INTENT(OUT) :: n_a_d
442 
443  INTEGER :: n, na, inc, i, j, k, ia
444 
445  na = SIZE(a)
446 
447 ! sort phase
448 
449  IF (na == 0) THEN
450  n_a_d = 0
451  RETURN
452  ENDIF
453 
454  inc = 1
455  DO WHILE (inc <= na)
456  inc = inc * 3
457  inc = inc + 1
458  ENDDO
459 
460  DO WHILE (inc > 1)
461  inc = inc/3
462  DO i = inc + 1, na
463  ia = a(i)
464  j = i
465  DO WHILE (a(j-inc) > ia)
466  a(j) = a(j-inc)
467  j = j - inc
468  IF (j <= inc) EXIT
469  ENDDO
470  a(j) = ia
471  ENDDO
472  ENDDO
473 
474 ! compression phase
475 
476  n = 1
477  a_d(n) = a(1)
478  DO k = 2, na
479  IF (a(k) > a(k-1)) THEN
480  n = n + 1
481  a_d(n) = a(k)
482  ENDIF
483  ENDDO
484 
485  n_a_d = n
486 
487  a_d(n_a_d + 1 : na) = 0
488 
489 END SUBROUTINE sort_diff
490 
491 END SUBROUTINE dir_nodes_sides_gen
492 
493 !-------------------------------------------------------------------------------
494 
495 SUBROUTINE dirichlet_nodes(jjs_in, sides_in, dir_in, js_d)
496 
497  INTEGER, DIMENSION(:,:), INTENT(IN) :: jjs_in
498  INTEGER, DIMENSION(:), INTENT(IN) :: sides_in
499  LOGICAL, DIMENSION(:), INTENT(IN) :: dir_in
500  INTEGER, DIMENSION(:), POINTER :: js_d
501  INTEGER:: j_size
502 
503  CALL dir_nodes_size(jjs_in, sides_in, dir_in, j_size)
504 ! IF (ASSOCIATED(js_d)) THEN
505 ! DEALLOCATE(js_d)
506 ! END IF
507  ALLOCATE (js_d(j_size))
508  CALL dir_nodes_gen(jjs_in, sides_in, dir_in, js_d)
509 
510 END SUBROUTINE dirichlet_nodes
511 
512 
513 SUBROUTINE dirichlet_nodes_sides(jjs_in, sides_in, dir_in, js_d, sides_D)
514 
515  INTEGER, DIMENSION(:,:), INTENT(IN) :: jjs_in
516  INTEGER, DIMENSION(:), INTENT(IN) :: sides_in
517  LOGICAL, DIMENSION(:), INTENT(IN) :: dir_in
518  INTEGER, DIMENSION(:), POINTER :: js_d, sides_d
519  INTEGER:: j_size
520 
521  CALL dir_nodes_size(jjs_in, sides_in, dir_in, j_size)
522 ! IF (ASSOCIATED(js_d)) THEN
523 ! DEALLOCATE(js_d)
524 ! END IF
525  ALLOCATE (js_d(j_size), sides_d(j_size))
526  CALL dir_nodes_sides_gen(jjs_in, sides_in, dir_in, js_d, sides_d)
527 
528 END SUBROUTINE dirichlet_nodes_sides
529 
530 SUBROUTINE dirichlet_nodes_bloc(jjs_in, sides_in, dir_in, &
531  nb_bloc, bloc_size, js_d)
532 
533  INTEGER, DIMENSION(:,:), INTENT(IN) :: jjs_in
534  INTEGER, DIMENSION(:), INTENT(IN) :: sides_in
535  LOGICAL, DIMENSION(:), INTENT(IN) :: dir_in
536  INTEGER, INTENT(IN) :: nb_bloc, bloc_size
537  INTEGER, DIMENSION(:), POINTER :: js_d_s, js_d
538  INTEGER:: j_size, n0, n_d, k
539 
540  CALL dir_nodes_size(jjs_in, sides_in, dir_in, j_size)
541  ALLOCATE (js_d_s(j_size))
542  CALL dir_nodes_gen(jjs_in, sides_in, dir_in, js_d_s)
543  n_d = SIZE(js_d_s)
544  ALLOCATE(js_d(nb_bloc*n_d))
545  DO k = 1, nb_bloc
546  n0 = (k-1)*n_d
547  js_d(n0+1:n0+n_d) = js_d_s + (k-1)*bloc_size
548  END DO
549  DEALLOCATE (js_d_s)
550 
551 END SUBROUTINE dirichlet_nodes_bloc
552 
553 
554 END MODULE dir_nodes
subroutine dir_nodes_size(js, sides, Dir, j_D_size)
Definition: dir_nodes.f90:124
subroutine dirichlet_m(js, ia, ja, a0)
Definition: dir_nodes.f90:42
subroutine dir_nodes_gen(js, sides, Dir, j_D)
Definition: dir_nodes.f90:243
subroutine dirichlet_bloc_m(js_D, ia, ja, a0)
Definition: dir_nodes.f90:95
subroutine precond_mat(ia, aa, vect)
Definition: dir_nodes.f90:8
subroutine dirichlet_rescale_m(js, ia, ja, alpha, a0)
Definition: dir_nodes.f90:69
subroutine dirichlet_nodes(jjs_in, sides_in, dir_in, js_d)
Definition: dir_nodes.f90:495
subroutine dirichlet_nodes_sides(jjs_in, sides_in, dir_in, js_d, sides_D)
Definition: dir_nodes.f90:513
subroutine dirichlet_nodes_bloc(jjs_in, sides_in, dir_in, nb_bloc, bloc_size, js_d)
Definition: dir_nodes.f90:530
subroutine dir_nodes_sides_gen(js, sides, Dir, j_D, s_D)
Definition: dir_nodes.f90:360
subroutine sort_diff(a, a_d, n_a_d)
Definition: dir_nodes.f90:176