1 |
|
2 |
subroutine dgscale( nn, gold, xdiff, diag, rmin ) |
3 |
|
4 |
|
5 |
c ================================================================== |
6 |
c SUBROUTINE dgscale |
7 |
c ================================================================== |
8 |
c |
9 |
c o computes new preconditioner and writes it to OPWARMD |
10 |
c |
11 |
c o started: ??? not reproducible |
12 |
c |
13 |
c o Version: 2.1.0, 02-Mar-2000: Patrick Heimbach, MIT/EAPS |
14 |
c |
15 |
c ================================================================== |
16 |
c SUBROUTINE dgscale |
17 |
c ================================================================== |
18 |
|
19 |
implicit none |
20 |
|
21 |
#include "blas1.h" |
22 |
include 'mpif.h' |
23 |
|
24 |
integer nn |
25 |
double precision gold(nn), xdiff(nn), diag(nn) |
26 |
|
27 |
integer i |
28 |
double precision r1, rmin, den |
29 |
|
30 |
double precision temp |
31 |
integer status(MPI_STATUS_SIZE),ierr |
32 |
integer myid, nprocs,mystart,myend |
33 |
common /mpi_parm/ myid,nprocs,mystart,myend |
34 |
|
35 |
c----------------------------------------- |
36 |
c read diagonal |
37 |
c----------------------------------------- |
38 |
call dostore( nn, diag, .false., 3 ) |
39 |
|
40 |
r1 = 0. |
41 |
do i = 1, nn |
42 |
r1 = r1 + gold(i)*gold(i)*diag(i) |
43 |
end do |
44 |
|
45 |
temp = r1 |
46 |
call MPI_ALLREDUCE(temp,r1,1,MPI_DOUBLE_PRECISION,MPI_SUM, |
47 |
& MPI_COMM_WORLD,ierr) |
48 |
r1 = 1.0 / r1 |
49 |
|
50 |
call DSCAL( nn, r1, diag, 1 ) |
51 |
|
52 |
c----------------------------------------- |
53 |
c update the diagonal |
54 |
c (gg is used as an auxiliary vector) |
55 |
c----------------------------------------- |
56 |
|
57 |
den = 0.0 |
58 |
|
59 |
do i = 1, nn |
60 |
cph( |
61 |
if (diag(i).LE.0) then |
62 |
cph print *, 'pathei-lsopt: in dgscale; diag = 0 for i=', i |
63 |
diag(i) = rmin |
64 |
end if |
65 |
cph) |
66 |
den = den + xdiff(i)*xdiff(i) / diag(i) |
67 |
end do |
68 |
|
69 |
temp=den |
70 |
call MPI_ALLREDUCE(temp,den,1,MPI_DOUBLE_PRECISION,MPI_SUM, |
71 |
& MPI_COMM_WORLD,ierr) |
72 |
|
73 |
do i = 1, nn |
74 |
diag(i) = 1./ |
75 |
$ (1./diag(i)+gold(i)**2-(xdiff(i)/diag(i))**2/den) |
76 |
if (diag(i).le.0.) then |
77 |
diag(i) = rmin |
78 |
endif |
79 |
end do |
80 |
|
81 |
c----------------------------------------- |
82 |
c write diagonal |
83 |
c----------------------------------------- |
84 |
call dostore( nn, diag, .true., 3 ) |
85 |
|
86 |
return |
87 |
end |