mirror of
https://github.com/HongjianFang/DSurfTomo.git
synced 2025-05-05 22:31:14 +08:00
new release 2016
share to public
This commit is contained in:
parent
cd7d0eb0a0
commit
3ac475560e
2
configure
vendored
2
configure
vendored
@ -12,5 +12,5 @@ os.system('make clean')
|
||||
os.system('make')
|
||||
os.system('cp DSurfTomo ../bin')
|
||||
print '--------------------------------------'
|
||||
print 'surf_tomo install over'
|
||||
print 'Finishing DSurfTomo compiling'
|
||||
print '--------------------------------------'
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,20 +0,0 @@
|
||||
CMD = DSurfTomo
|
||||
FC = gfortran
|
||||
FFLAGS = -O3 -ffixed-line-length-none -ffloat-store\
|
||||
-W -fbounds-check -m64 -mcmodel=medium
|
||||
F90SRCS = lsmrDataModule.f90 lsmrblasInterface.f90\
|
||||
lsmrblas.f90 lsmrModule.f90 delsph.f90\
|
||||
aprod.f90 gaussian.f90 main.f90
|
||||
FSRCS = surfdisp96.f
|
||||
OBJS = $(F90SRCS:%.f90=%.o) $(FSRCS:%.f=%.o) CalSurfG.o
|
||||
all:$(CMD)
|
||||
$(CMD):$(OBJS)
|
||||
$(FC) -fopenmp $^ -o $@
|
||||
CalSurfG.o:CalSurfG.f90
|
||||
$(FC) -fopenmp $(FFLAGS) -c $< -o $@
|
||||
%.o: %.f90
|
||||
$(FC) $(FFLAGS) -c $(@F:.o=.f90) -o $@
|
||||
%.o: %.f
|
||||
$(FC) $(FFLAGS) -c $(@F:.o=.f) -o $@
|
||||
clean:
|
||||
rm *.o *.mod $(CMD)
|
@ -1,60 +0,0 @@
|
||||
!c--- This file is from hypoDD by Felix Waldhauser ---------
|
||||
!c-------------------------Modified by Haijiang Zhang-------
|
||||
!c Multiply a matrix by a vector
|
||||
!c Version for use with sparse matrix specified by
|
||||
!c output of subroutine sparse for use with LSQR
|
||||
|
||||
subroutine aprod(mode, m, n, x, y, leniw, lenrw, iw, rw)
|
||||
|
||||
implicit none
|
||||
|
||||
!c Parameters:
|
||||
integer mode ! ==1: Compute y = y + a*x
|
||||
! y is altered without changing x
|
||||
! ==2: Compute x = x + a(transpose)*y
|
||||
! x is altered without changing y
|
||||
integer m, n ! Row and column dimensions of a
|
||||
real x(n), y(m) ! Input vectors
|
||||
integer :: leniw
|
||||
integer lenrw
|
||||
integer iw(leniw) ! Integer work vector containing:
|
||||
! iw[1] Number of non-zero elements in a
|
||||
! iw[2:iw[1]+1] Row indices of non-zero elements
|
||||
! iw[iw[1]+2:2*iw[1]+1] Column indices
|
||||
real rw(lenrw) ! [1..iw[1]] Non-zero elements of a
|
||||
|
||||
!c Local variables:
|
||||
integer i1
|
||||
integer j1
|
||||
integer k
|
||||
integer kk
|
||||
|
||||
!c set the ranges the indices in vector iw
|
||||
|
||||
kk=iw(1)
|
||||
i1=1
|
||||
j1=kk+1
|
||||
|
||||
!c main iteration loop
|
||||
|
||||
do k = 1,kk
|
||||
|
||||
if (mode.eq.1) then
|
||||
|
||||
!c compute y = y + a*x
|
||||
|
||||
y(iw(i1+k)) = y(iw(i1+k)) + rw(k)*x(iw(j1+k))
|
||||
|
||||
else
|
||||
|
||||
!c compute x = x + a(transpose)*y
|
||||
|
||||
x(iw(j1+k)) = x(iw(j1+k)) + rw(k)*y(iw(i1+k))
|
||||
|
||||
endif
|
||||
enddo
|
||||
|
||||
! 100 continue
|
||||
|
||||
return
|
||||
end
|
@ -1,28 +0,0 @@
|
||||
subroutine delsph(flat1,flon1,flat2,flon2,del)
|
||||
implicit none
|
||||
real,parameter:: R=6371.0
|
||||
REAL,parameter:: pi=3.1415926535898
|
||||
real flat1,flat2
|
||||
real flon1,flon2
|
||||
real del
|
||||
|
||||
real dlat
|
||||
real dlon
|
||||
real lat1
|
||||
real lat2
|
||||
real a
|
||||
real c
|
||||
|
||||
|
||||
!dlat=(flat2-flat1)*pi/180
|
||||
!dlon=(flon2-flon1)*pi/180
|
||||
!lat1=flat1*pi/180
|
||||
!lat2=flat2*pi/180
|
||||
dlat=flat2-flat1
|
||||
dlon=flon2-flon1
|
||||
lat1=pi/2-flat1
|
||||
lat2=pi/2-flat2
|
||||
a=sin(dlat/2)*sin(dlat/2)+sin(dlon/2)*sin(dlon/2)*cos(lat1)*cos(lat2)
|
||||
c=2*atan2(sqrt(a),sqrt(1-a))
|
||||
del=R*c
|
||||
end subroutine
|
@ -1,31 +0,0 @@
|
||||
real function gaussian()
|
||||
implicit none
|
||||
! real rd
|
||||
|
||||
real x1,x2,w,y1
|
||||
real y2
|
||||
real n1,n2
|
||||
integer use_last
|
||||
integer ii,jj
|
||||
|
||||
use_last=0
|
||||
y2=0
|
||||
w=2.0
|
||||
if(use_last.ne.0) then
|
||||
y1=y2
|
||||
use_last=0
|
||||
else
|
||||
do while (w.ge.1.0)
|
||||
call random_number(n1)
|
||||
call random_number(n2)
|
||||
x1=2.0*n1-1.0
|
||||
x2=2.0*n2-1.0
|
||||
w = x1 * x1 + x2 * x2
|
||||
enddo
|
||||
w=((-2.0*log(w))/w)**0.5
|
||||
y1=x1*w
|
||||
y2=x2*w
|
||||
use_last=1
|
||||
endif
|
||||
gaussian=y1
|
||||
end function
|
@ -1,24 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrDataModule.f90
|
||||
!
|
||||
! Defines real(dp) and a few constants for use in other modules.
|
||||
!
|
||||
! 24 Oct 2007: Allows floating-point precision dp to be defined
|
||||
! in exactly one place (here). Note that we need
|
||||
! use lsmrDataModule
|
||||
! at the beginning of modules AND inside interfaces.
|
||||
! zero and one are not currently used by LSMR,
|
||||
! but this shows how they should be declared
|
||||
! by a user routine that does need them.
|
||||
! 16 Jul 2010: LSMR version derived from LSQR equivalent.
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
module lsmrDataModule
|
||||
|
||||
implicit none
|
||||
|
||||
intrinsic :: selected_real_kind
|
||||
integer, parameter, public :: dp = selected_real_kind(4)
|
||||
real(dp), parameter, public :: zero = 0.0_dp, one = 1.0_dp
|
||||
|
||||
end module lsmrDataModule
|
@ -1,754 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrModule.f90
|
||||
!
|
||||
! LSMR
|
||||
!
|
||||
! LSMR solves Ax = b or min ||Ax - b|| with or without damping,
|
||||
! using the iterative algorithm of David Fong and Michael Saunders:
|
||||
! http://www.stanford.edu/group/SOL/software/lsmr.html
|
||||
!
|
||||
! Maintained by
|
||||
! David Fong <clfong@stanford.edu>
|
||||
! Michael Saunders <saunders@stanford.edu>
|
||||
! Systems Optimization Laboratory (SOL)
|
||||
! Stanford University
|
||||
! Stanford, CA 94305-4026, USA
|
||||
!
|
||||
! 17 Jul 2010: F90 LSMR derived from F90 LSQR and lsqr.m.
|
||||
! 07 Sep 2010: Local reorthogonalization now works (localSize > 0).
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
module lsmrModule
|
||||
|
||||
use lsmrDataModule, only : dp
|
||||
use lsmrblasInterface, only : dnrm2, dscal
|
||||
implicit none
|
||||
private
|
||||
public :: LSMR
|
||||
|
||||
contains
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
! subroutine LSMR ( m, n, Aprod1, Aprod2, b, damp, &
|
||||
! atol, btol, conlim, itnlim, localSize, nout, &
|
||||
! x, istop, itn, normA, condA, normr, normAr, normx )
|
||||
subroutine LSMR ( m, n, leniw, lenrw,iw,rw, b, damp, &
|
||||
atol, btol, conlim, itnlim, localSize, nout, &
|
||||
x, istop, itn, normA, condA, normr, normAr, normx )
|
||||
|
||||
integer, intent(in) :: leniw
|
||||
integer, intent(in) :: lenrw
|
||||
integer, intent(in) :: iw(leniw)
|
||||
real, intent(in) :: rw(lenrw)
|
||||
|
||||
integer, intent(in) :: m, n, itnlim, localSize, nout
|
||||
integer, intent(out) :: istop, itn
|
||||
real(dp), intent(in) :: b(m)
|
||||
real(dp), intent(out) :: x(n)
|
||||
real(dp), intent(in) :: atol, btol, conlim, damp
|
||||
real(dp), intent(out) :: normA, condA, normr, normAr, normx
|
||||
|
||||
interface
|
||||
subroutine aprod(mode,m,n,x,y,leniw,lenrw,iw,rw) ! y := y + A*x
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: mode,lenrw
|
||||
integer, intent(in) :: leniw
|
||||
real, intent(in) :: rw(lenrw)
|
||||
integer, intent(in) :: iw(leniw)
|
||||
integer, intent(in) :: m,n
|
||||
real(dp), intent(inout) :: x(n)
|
||||
real(dp), intent(inout) :: y(m)
|
||||
end subroutine aprod
|
||||
! subroutine Aprod1(m,n,x,y) ! y := y + A*x
|
||||
! use lsmrDataModule, only : dp
|
||||
! integer, intent(in) :: m,n
|
||||
! real(dp), intent(in) :: x(n)
|
||||
! real(dp), intent(inout) :: y(m)
|
||||
! end subroutine Aprod1
|
||||
!
|
||||
! subroutine Aprod2(m,n,x,y) ! x := x + A'*y
|
||||
! use lsmrDataModule, only : dp
|
||||
! integer, intent(in) :: m,n
|
||||
! real(dp), intent(inout) :: x(n)
|
||||
! real(dp), intent(in) :: y(m)
|
||||
! end subroutine Aprod2
|
||||
end interface
|
||||
|
||||
!-------------------------------------------------------------------
|
||||
! LSMR finds a solution x to the following problems:
|
||||
!
|
||||
! 1. Unsymmetric equations: Solve A*x = b
|
||||
!
|
||||
! 2. Linear least squares: Solve A*x = b
|
||||
! in the least-squares sense
|
||||
!
|
||||
! 3. Damped least squares: Solve ( A )*x = ( b )
|
||||
! ( damp*I ) ( 0 )
|
||||
! in the least-squares sense
|
||||
!
|
||||
! where A is a matrix with m rows and n columns, b is an m-vector,
|
||||
! and damp is a scalar. (All quantities are real.)
|
||||
! The matrix A is treated as a linear operator. It is accessed
|
||||
! by means of subroutine calls with the following purpose:
|
||||
!
|
||||
! call Aprod1(m,n,x,y) must compute y = y + A*x without altering x.
|
||||
! call Aprod2(m,n,x,y) must compute x = x + A'*y without altering y.
|
||||
!
|
||||
! LSMR uses an iterative method to approximate the solution.
|
||||
! The number of iterations required to reach a certain accuracy
|
||||
! depends strongly on the scaling of the problem. Poor scaling of
|
||||
! the rows or columns of A should therefore be avoided where
|
||||
! possible.
|
||||
!
|
||||
! For example, in problem 1 the solution is unaltered by
|
||||
! row-scaling. If a row of A is very small or large compared to
|
||||
! the other rows of A, the corresponding row of ( A b ) should be
|
||||
! scaled up or down.
|
||||
!
|
||||
! In problems 1 and 2, the solution x is easily recovered
|
||||
! following column-scaling. Unless better information is known,
|
||||
! the nonzero columns of A should be scaled so that they all have
|
||||
! the same Euclidean norm (e.g., 1.0).
|
||||
!
|
||||
! In problem 3, there is no freedom to re-scale if damp is
|
||||
! nonzero. However, the value of damp should be assigned only
|
||||
! after attention has been paid to the scaling of A.
|
||||
!
|
||||
! The parameter damp is intended to help regularize
|
||||
! ill-conditioned systems, by preventing the true solution from
|
||||
! being very large. Another aid to regularization is provided by
|
||||
! the parameter condA, which may be used to terminate iterations
|
||||
! before the computed solution becomes very large.
|
||||
!
|
||||
! Note that x is not an input parameter.
|
||||
! If some initial estimate x0 is known and if damp = 0,
|
||||
! one could proceed as follows:
|
||||
!
|
||||
! 1. Compute a residual vector r0 = b - A*x0.
|
||||
! 2. Use LSMR to solve the system A*dx = r0.
|
||||
! 3. Add the correction dx to obtain a final solution x = x0 + dx.
|
||||
!
|
||||
! This requires that x0 be available before and after the call
|
||||
! to LSMR. To judge the benefits, suppose LSMR takes k1 iterations
|
||||
! to solve A*x = b and k2 iterations to solve A*dx = r0.
|
||||
! If x0 is "good", norm(r0) will be smaller than norm(b).
|
||||
! If the same stopping tolerances atol and btol are used for each
|
||||
! system, k1 and k2 will be similar, but the final solution x0 + dx
|
||||
! should be more accurate. The only way to reduce the total work
|
||||
! is to use a larger stopping tolerance for the second system.
|
||||
! If some value btol is suitable for A*x = b, the larger value
|
||||
! btol*norm(b)/norm(r0) should be suitable for A*dx = r0.
|
||||
!
|
||||
! Preconditioning is another way to reduce the number of iterations.
|
||||
! If it is possible to solve a related system M*x = b efficiently,
|
||||
! where M approximates A in some helpful way
|
||||
! (e.g. M - A has low rank or its elements are small relative to
|
||||
! those of A), LSMR may converge more rapidly on the system
|
||||
! A*M(inverse)*z = b,
|
||||
! after which x can be recovered by solving M*x = z.
|
||||
!
|
||||
! NOTE: If A is symmetric, LSMR should not be used!
|
||||
! Alternatives are the symmetric conjugate-gradient method (CG)
|
||||
! and/or SYMMLQ.
|
||||
! SYMMLQ is an implementation of symmetric CG that applies to
|
||||
! any symmetric A and will converge more rapidly than LSMR.
|
||||
! If A is positive definite, there are other implementations of
|
||||
! symmetric CG that require slightly less work per iteration
|
||||
! than SYMMLQ (but will take the same number of iterations).
|
||||
!
|
||||
!
|
||||
! Notation
|
||||
! --------
|
||||
! The following quantities are used in discussing the subroutine
|
||||
! parameters:
|
||||
!
|
||||
! Abar = ( A ), bbar = (b)
|
||||
! (damp*I) (0)
|
||||
!
|
||||
! r = b - A*x, rbar = bbar - Abar*x
|
||||
!
|
||||
! normr = sqrt( norm(r)**2 + damp**2 * norm(x)**2 )
|
||||
! = norm( rbar )
|
||||
!
|
||||
! eps = the relative precision of floating-point arithmetic.
|
||||
! On most machines, eps is about 1.0e-7 and 1.0e-16
|
||||
! in single and double precision respectively.
|
||||
! We expect eps to be about 1e-16 always.
|
||||
!
|
||||
! LSMR minimizes the function normr with respect to x.
|
||||
!
|
||||
!
|
||||
! Parameters
|
||||
! ----------
|
||||
! m input m, the number of rows in A.
|
||||
!
|
||||
! n input n, the number of columns in A.
|
||||
!
|
||||
! Aprod1, Aprod2 See above.
|
||||
!
|
||||
! damp input The damping parameter for problem 3 above.
|
||||
! (damp should be 0.0 for problems 1 and 2.)
|
||||
! If the system A*x = b is incompatible, values
|
||||
! of damp in the range 0 to sqrt(eps)*norm(A)
|
||||
! will probably have a negligible effect.
|
||||
! Larger values of damp will tend to decrease
|
||||
! the norm of x and reduce the number of
|
||||
! iterations required by LSMR.
|
||||
!
|
||||
! The work per iteration and the storage needed
|
||||
! by LSMR are the same for all values of damp.
|
||||
!
|
||||
! b(m) input The rhs vector b.
|
||||
!
|
||||
! x(n) output Returns the computed solution x.
|
||||
!
|
||||
! atol input An estimate of the relative error in the data
|
||||
! defining the matrix A. For example, if A is
|
||||
! accurate to about 6 digits, set atol = 1.0e-6.
|
||||
!
|
||||
! btol input An estimate of the relative error in the data
|
||||
! defining the rhs b. For example, if b is
|
||||
! accurate to about 6 digits, set btol = 1.0e-6.
|
||||
!
|
||||
! conlim input An upper limit on cond(Abar), the apparent
|
||||
! condition number of the matrix Abar.
|
||||
! Iterations will be terminated if a computed
|
||||
! estimate of cond(Abar) exceeds conlim.
|
||||
! This is intended to prevent certain small or
|
||||
! zero singular values of A or Abar from
|
||||
! coming into effect and causing unwanted growth
|
||||
! in the computed solution.
|
||||
!
|
||||
! conlim and damp may be used separately or
|
||||
! together to regularize ill-conditioned systems.
|
||||
!
|
||||
! Normally, conlim should be in the range
|
||||
! 1000 to 1/eps.
|
||||
! Suggested value:
|
||||
! conlim = 1/(100*eps) for compatible systems,
|
||||
! conlim = 1/(10*sqrt(eps)) for least squares.
|
||||
!
|
||||
! Note: Any or all of atol, btol, conlim may be set to zero.
|
||||
! The effect will be the same as the values eps, eps, 1/eps.
|
||||
!
|
||||
! itnlim input An upper limit on the number of iterations.
|
||||
! Suggested value:
|
||||
! itnlim = n/2 for well-conditioned systems
|
||||
! with clustered singular values,
|
||||
! itnlim = 4*n otherwise.
|
||||
!
|
||||
! localSize input No. of vectors for local reorthogonalization.
|
||||
! 0 No reorthogonalization is performed.
|
||||
! >0 This many n-vectors "v" (the most recent ones)
|
||||
! are saved for reorthogonalizing the next v.
|
||||
! localSize need not be more than min(m,n).
|
||||
! At most min(m,n) vectors will be allocated.
|
||||
!
|
||||
! nout input File number for printed output. If positive,
|
||||
! a summary will be printed on file nout.
|
||||
!
|
||||
! istop output An integer giving the reason for termination:
|
||||
!
|
||||
! 0 x = 0 is the exact solution.
|
||||
! No iterations were performed.
|
||||
!
|
||||
! 1 The equations A*x = b are probably compatible.
|
||||
! Norm(A*x - b) is sufficiently small, given the
|
||||
! values of atol and btol.
|
||||
!
|
||||
! 2 damp is zero. The system A*x = b is probably
|
||||
! not compatible. A least-squares solution has
|
||||
! been obtained that is sufficiently accurate,
|
||||
! given the value of atol.
|
||||
!
|
||||
! 3 damp is nonzero. A damped least-squares
|
||||
! solution has been obtained that is sufficiently
|
||||
! accurate, given the value of atol.
|
||||
!
|
||||
! 4 An estimate of cond(Abar) has exceeded conlim.
|
||||
! The system A*x = b appears to be ill-conditioned,
|
||||
! or there could be an error in Aprod1 or Aprod2.
|
||||
!
|
||||
! 5 The iteration limit itnlim was reached.
|
||||
!
|
||||
! itn output The number of iterations performed.
|
||||
!
|
||||
! normA output An estimate of the Frobenius norm of Abar.
|
||||
! This is the square-root of the sum of squares
|
||||
! of the elements of Abar.
|
||||
! If damp is small and the columns of A
|
||||
! have all been scaled to have length 1.0,
|
||||
! normA should increase to roughly sqrt(n).
|
||||
! A radically different value for normA may
|
||||
! indicate an error in Aprod1 or Aprod2.
|
||||
!
|
||||
! condA output An estimate of cond(Abar), the condition
|
||||
! number of Abar. A very high value of condA
|
||||
! may again indicate an error in Aprod1 or Aprod2.
|
||||
!
|
||||
! normr output An estimate of the final value of norm(rbar),
|
||||
! the function being minimized (see notation
|
||||
! above). This will be small if A*x = b has
|
||||
! a solution.
|
||||
!
|
||||
! normAr output An estimate of the final value of
|
||||
! norm( Abar'*rbar ), the norm of
|
||||
! the residual for the normal equations.
|
||||
! This should be small in all cases. (normAr
|
||||
! will often be smaller than the true value
|
||||
! computed from the output vector x.)
|
||||
!
|
||||
! normx output An estimate of norm(x) for the final solution x.
|
||||
!
|
||||
! Subroutines and functions used
|
||||
! ------------------------------
|
||||
! BLAS dscal, dnrm2
|
||||
! USER Aprod1, Aprod2
|
||||
!
|
||||
! Precision
|
||||
! ---------
|
||||
! The number of iterations required by LSMR will decrease
|
||||
! if the computation is performed in higher precision.
|
||||
! At least 15-digit arithmetic should normally be used.
|
||||
! "real(dp)" declarations should normally be 8-byte words.
|
||||
! If this ever changes, the BLAS routines dnrm2, dscal
|
||||
! (Lawson, et al., 1979) will also need to be changed.
|
||||
!
|
||||
!
|
||||
! Reference
|
||||
! ---------
|
||||
! http://www.stanford.edu/group/SOL/software/lsmr.html
|
||||
! ------------------------------------------------------------------
|
||||
!
|
||||
! LSMR development:
|
||||
! 21 Sep 2007: Fortran 90 version of LSQR implemented.
|
||||
! Aprod1, Aprod2 implemented via f90 interface.
|
||||
! 17 Jul 2010: LSMR derived from LSQR and lsmr.m.
|
||||
! 07 Sep 2010: Local reorthogonalization now working.
|
||||
!-------------------------------------------------------------------
|
||||
|
||||
intrinsic :: abs, dot_product, min, max, sqrt
|
||||
|
||||
! Local arrays and variables
|
||||
real(dp) :: h(n), hbar(n), u(m), v(n), w(n), localV(n,min(localSize,m,n))
|
||||
logical :: damped, localOrtho, localVQueueFull, prnt, show
|
||||
integer :: i, localOrthoCount, localOrthoLimit, localPointer, localVecs, &
|
||||
pcount, pfreq
|
||||
real(dp) :: alpha, alphabar, alphahat, &
|
||||
beta, betaacute, betacheck, betad, betadd, betahat, &
|
||||
normb, c, cbar, chat, ctildeold, ctol, &
|
||||
d, maxrbar, minrbar, normA2, &
|
||||
rho, rhobar, rhobarold, rhodold, rhoold, rhotemp, &
|
||||
rhotildeold, rtol, s, sbar, shat, stildeold, &
|
||||
t1, taud, tautildeold, test1, test2, test3, &
|
||||
thetabar, thetanew, thetatilde, thetatildeold, &
|
||||
zeta, zetabar, zetaold
|
||||
|
||||
! Local constants
|
||||
real(dp), parameter :: zero = 0.0_dp, one = 1.0_dp
|
||||
character(len=*), parameter :: enter = ' Enter LSMR. '
|
||||
character(len=*), parameter :: exitt = ' Exit LSMR. '
|
||||
character(len=*), parameter :: msg(0:7) = &
|
||||
(/ 'The exact solution is x = 0 ', &
|
||||
'Ax - b is small enough, given atol, btol ', &
|
||||
'The least-squares solution is good enough, given atol', &
|
||||
'The estimate of cond(Abar) has exceeded conlim ', &
|
||||
'Ax - b is small enough for this machine ', &
|
||||
'The LS solution is good enough for this machine ', &
|
||||
'Cond(Abar) seems to be too large for this machine ', &
|
||||
'The iteration limit has been reached ' /)
|
||||
!-------------------------------------------------------------------
|
||||
|
||||
|
||||
! Initialize.
|
||||
|
||||
localVecs = min(localSize,m,n)
|
||||
show = nout > 0
|
||||
if (show) then
|
||||
write(nout, 1000) enter,m,n,damp,atol,conlim,btol,itnlim,localVecs
|
||||
end if
|
||||
|
||||
pfreq = 20 ! print frequency (for repeating the heading)
|
||||
pcount = 0 ! print counter
|
||||
damped = damp > zero !
|
||||
|
||||
!-------------------------------------------------------------------
|
||||
! Set up the first vectors u and v for the bidiagonalization.
|
||||
! These satisfy beta*u = b, alpha*v = A(transpose)*u.
|
||||
!-------------------------------------------------------------------
|
||||
u(1:m) = b(1:m)
|
||||
v(1:n) = zero
|
||||
x(1:n) = zero
|
||||
|
||||
alpha = zero
|
||||
beta = dnrm2 (m, u, 1)
|
||||
|
||||
if (beta > zero) then
|
||||
call dscal (m, (one/beta), u, 1)
|
||||
! call Aprod2(m, n, v, u) ! v = A'*u
|
||||
call aprod(2,m,n,v,u,leniw,lenrw,iw,rw)
|
||||
alpha = dnrm2 (n, v, 1)
|
||||
end if
|
||||
|
||||
if (alpha > zero) then
|
||||
call dscal (n, (one/alpha), v, 1)
|
||||
w = v
|
||||
end if
|
||||
|
||||
normAr = alpha*beta
|
||||
if (normAr == zero) go to 800
|
||||
|
||||
! Initialization for local reorthogonalization.
|
||||
|
||||
localOrtho = .false.
|
||||
if (localVecs > 0) then
|
||||
localPointer = 1
|
||||
localOrtho = .true.
|
||||
localVQueueFull = .false.
|
||||
localV(:,1) = v
|
||||
end if
|
||||
|
||||
! Initialize variables for 1st iteration.
|
||||
|
||||
itn = 0
|
||||
zetabar = alpha*beta
|
||||
alphabar = alpha
|
||||
rho = 1
|
||||
rhobar = 1
|
||||
cbar = 1
|
||||
sbar = 0
|
||||
|
||||
h = v
|
||||
hbar(1:n) = zero
|
||||
x(1:n) = zero
|
||||
|
||||
! Initialize variables for estimation of ||r||.
|
||||
|
||||
betadd = beta
|
||||
betad = 0
|
||||
rhodold = 1
|
||||
tautildeold = 0
|
||||
thetatilde = 0
|
||||
zeta = 0
|
||||
d = 0
|
||||
|
||||
! Initialize variables for estimation of ||A|| and cond(A).
|
||||
|
||||
normA2 = alpha**2
|
||||
maxrbar = 0_dp
|
||||
minrbar = 1e+30_dp
|
||||
|
||||
! Items for use in stopping rules.
|
||||
normb = beta
|
||||
istop = 0
|
||||
ctol = zero
|
||||
if (conlim > zero) ctol = one/conlim
|
||||
normr = beta
|
||||
|
||||
! Exit if b=0 or A'b = 0.
|
||||
|
||||
normAr = alpha * beta
|
||||
if (normAr == 0) then
|
||||
if (show) then
|
||||
write(nout,'(a)') msg(1)
|
||||
end if
|
||||
return
|
||||
end if
|
||||
|
||||
! Heading for iteration log.
|
||||
|
||||
if (show) then
|
||||
if (damped) then
|
||||
write(nout,1300)
|
||||
else
|
||||
write(nout,1200)
|
||||
end if
|
||||
test1 = one
|
||||
test2 = alpha/beta
|
||||
write(nout, 1500) itn,x(1),normr,normAr,test1,test2
|
||||
end if
|
||||
|
||||
!===================================================================
|
||||
! Main iteration loop.
|
||||
!===================================================================
|
||||
do
|
||||
itn = itn + 1
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! Perform the next step of the bidiagonalization to obtain the
|
||||
! next beta, u, alpha, v. These satisfy
|
||||
! beta*u = A*v - alpha*u,
|
||||
! alpha*v = A'*u - beta*v.
|
||||
!----------------------------------------------------------------
|
||||
call dscal (m,(- alpha), u, 1)
|
||||
! call Aprod1(m, n, v, u) ! u = A*v
|
||||
call aprod ( 1,m,n,v,u,leniw,lenrw,iw,rw )
|
||||
beta = dnrm2 (m, u, 1)
|
||||
|
||||
if (beta > zero) then
|
||||
call dscal (m, (one/beta), u, 1)
|
||||
if (localOrtho) then ! Store v into the circular buffer localV.
|
||||
call localVEnqueue ! Store old v for local reorthog'n of new v.
|
||||
end if
|
||||
call dscal (n, (- beta), v, 1)
|
||||
|
||||
!call Aprod2(m, n, v, u) ! v = A'*u
|
||||
call aprod ( 2,m,n,v,u,leniw,lenrw,iw,rw )
|
||||
if (localOrtho) then ! Perform local reorthogonalization of V.
|
||||
call localVOrtho ! Local-reorthogonalization of new v.
|
||||
end if
|
||||
alpha = dnrm2 (n, v, 1)
|
||||
if (alpha > zero) then
|
||||
call dscal (n, (one/alpha), v, 1)
|
||||
end if
|
||||
end if
|
||||
|
||||
! At this point, beta = beta_{k+1}, alpha = alpha_{k+1}.
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! Construct rotation Qhat_{k,2k+1}.
|
||||
|
||||
alphahat = d2norm(alphabar, damp)
|
||||
chat = alphabar/alphahat
|
||||
shat = damp/alphahat
|
||||
|
||||
! Use a plane rotation (Q_i) to turn B_i to R_i.
|
||||
|
||||
rhoold = rho
|
||||
rho = d2norm(alphahat, beta)
|
||||
c = alphahat/rho
|
||||
s = beta/rho
|
||||
thetanew = s*alpha
|
||||
alphabar = c*alpha
|
||||
|
||||
! Use a plane rotation (Qbar_i) to turn R_i^T into R_i^bar.
|
||||
|
||||
rhobarold = rhobar
|
||||
zetaold = zeta
|
||||
thetabar = sbar*rho
|
||||
rhotemp = cbar*rho
|
||||
rhobar = d2norm(cbar*rho, thetanew)
|
||||
cbar = cbar*rho/rhobar
|
||||
sbar = thetanew/rhobar
|
||||
zeta = cbar*zetabar
|
||||
zetabar = - sbar*zetabar
|
||||
|
||||
! Update h, h_hat, x.
|
||||
|
||||
hbar = h - (thetabar*rho/(rhoold*rhobarold))*hbar
|
||||
x = x + (zeta/(rho*rhobar))*hbar
|
||||
h = v - (thetanew/rho)*h
|
||||
|
||||
! Estimate ||r||.
|
||||
|
||||
! Apply rotation Qhat_{k,2k+1}.
|
||||
betaacute = chat* betadd
|
||||
betacheck = - shat* betadd
|
||||
|
||||
! Apply rotation Q_{k,k+1}.
|
||||
betahat = c*betaacute
|
||||
betadd = - s*betaacute
|
||||
|
||||
! Apply rotation Qtilde_{k-1}.
|
||||
! betad = betad_{k-1} here.
|
||||
|
||||
thetatildeold = thetatilde
|
||||
rhotildeold = d2norm(rhodold, thetabar)
|
||||
ctildeold = rhodold/rhotildeold
|
||||
stildeold = thetabar/rhotildeold
|
||||
thetatilde = stildeold* rhobar
|
||||
rhodold = ctildeold* rhobar
|
||||
betad = - stildeold*betad + ctildeold*betahat
|
||||
|
||||
! betad = betad_k here.
|
||||
! rhodold = rhod_k here.
|
||||
|
||||
tautildeold = (zetaold - thetatildeold*tautildeold)/rhotildeold
|
||||
taud = (zeta - thetatilde*tautildeold)/rhodold
|
||||
d = d + betacheck**2
|
||||
normr = sqrt(d + (betad - taud)**2 + betadd**2)
|
||||
|
||||
! Estimate ||A||.
|
||||
normA2 = normA2 + beta**2
|
||||
normA = sqrt(normA2)
|
||||
normA2 = normA2 + alpha**2
|
||||
|
||||
! Estimate cond(A).
|
||||
maxrbar = max(maxrbar,rhobarold)
|
||||
if (itn > 1) then
|
||||
minrbar = min(minrbar,rhobarold)
|
||||
end if
|
||||
condA = max(maxrbar,rhotemp)/min(minrbar,rhotemp)
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! Test for convergence.
|
||||
!----------------------------------------------------------------
|
||||
|
||||
! Compute norms for convergence testing.
|
||||
normAr = abs(zetabar)
|
||||
normx = dnrm2(n, x, 1)
|
||||
|
||||
! Now use these norms to estimate certain other quantities,
|
||||
! some of which will be small near a solution.
|
||||
|
||||
test1 = normr /normb
|
||||
test2 = normAr/(normA*normr)
|
||||
test3 = one/condA
|
||||
t1 = test1/(one + normA*normx/normb)
|
||||
rtol = btol + atol*normA*normx/normb
|
||||
|
||||
! The following tests guard against extremely small values of
|
||||
! atol, btol or ctol. (The user may have set any or all of
|
||||
! the parameters atol, btol, conlim to 0.)
|
||||
! The effect is equivalent to the normAl tests using
|
||||
! atol = eps, btol = eps, conlim = 1/eps.
|
||||
|
||||
if (itn >= itnlim) istop = 7
|
||||
if (one+test3 <= one) istop = 6
|
||||
if (one+test2 <= one) istop = 5
|
||||
if (one+t1 <= one) istop = 4
|
||||
|
||||
! Allow for tolerances set by the user.
|
||||
|
||||
if ( test3 <= ctol) istop = 3
|
||||
if ( test2 <= atol) istop = 2
|
||||
if ( test1 <= rtol) istop = 1
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! See if it is time to print something.
|
||||
!----------------------------------------------------------------
|
||||
prnt = .false.
|
||||
if (show) then
|
||||
if (n <= 40) prnt = .true.
|
||||
if (itn <= 10) prnt = .true.
|
||||
if (itn >= itnlim-10) prnt = .true.
|
||||
if (mod(itn,10) == 0) prnt = .true.
|
||||
if (test3 <= 1.1*ctol) prnt = .true.
|
||||
if (test2 <= 1.1*atol) prnt = .true.
|
||||
if (test1 <= 1.1*rtol) prnt = .true.
|
||||
if (istop /= 0) prnt = .true.
|
||||
|
||||
if (prnt) then ! Print a line for this iteration
|
||||
if (pcount >= pfreq) then ! Print a heading first
|
||||
pcount = 0
|
||||
if (damped) then
|
||||
write(nout,1300)
|
||||
else
|
||||
write(nout,1200)
|
||||
end if
|
||||
end if
|
||||
pcount = pcount + 1
|
||||
write(nout,1500) itn,x(1),normr,normAr,test1,test2,normA,condA
|
||||
end if
|
||||
end if
|
||||
|
||||
if (istop /= 0) exit
|
||||
end do
|
||||
!===================================================================
|
||||
! End of iteration loop.
|
||||
!===================================================================
|
||||
|
||||
! Come here if normAr = 0, or if normal exit.
|
||||
|
||||
800 if (damped .and. istop==2) istop=3 ! Decide if istop = 2 or 3.
|
||||
if (show) then ! Print the stopping condition.
|
||||
write(nout, 2000) &
|
||||
exitt,istop,itn, &
|
||||
exitt,normA,condA, &
|
||||
exitt,normb, normx, &
|
||||
exitt,normr,normAr
|
||||
write(nout, 3000) &
|
||||
exitt, msg(istop)
|
||||
end if
|
||||
|
||||
return
|
||||
|
||||
1000 format(// a, ' Least-squares solution of Ax = b' &
|
||||
/ ' The matrix A has', i7, ' rows and', i7, ' columns' &
|
||||
/ ' damp =', es22.14 &
|
||||
/ ' atol =', es10.2, 15x, 'conlim =', es10.2 &
|
||||
/ ' btol =', es10.2, 15x, 'itnlim =', i10 &
|
||||
/ ' localSize (no. of vectors for local reorthogonalization) =', i7)
|
||||
1200 format(/ " Itn x(1) norm r A'r ", &
|
||||
' Compatible LS norm A cond A')
|
||||
1300 format(/ " Itn x(1) norm rbar Abar'rbar", &
|
||||
' Compatible LS norm Abar cond Abar')
|
||||
1500 format(i6, 2es17.9, 5es10.2)
|
||||
2000 format(/ a, 5x, 'istop =', i2, 15x, 'itn =', i8 &
|
||||
/ a, 5x, 'normA =', es12.5, 5x, 'condA =', es12.5 &
|
||||
/ a, 5x, 'normb =', es12.5, 5x, 'normx =', es12.5 &
|
||||
/ a, 5x, 'normr =', es12.5, 5x, 'normAr =', es12.5)
|
||||
3000 format(a, 5x, a)
|
||||
|
||||
contains
|
||||
|
||||
function d2norm( a, b )
|
||||
|
||||
real(dp) :: d2norm
|
||||
real(dp), intent(in) :: a, b
|
||||
|
||||
!-------------------------------------------------------------------
|
||||
! d2norm returns sqrt( a**2 + b**2 )
|
||||
! with precautions to avoid overflow.
|
||||
!
|
||||
! 21 Mar 1990: First version.
|
||||
! 17 Sep 2007: Fortran 90 version.
|
||||
! 24 Oct 2007: User real(dp) instead of compiler option -r8.
|
||||
!-------------------------------------------------------------------
|
||||
|
||||
intrinsic :: abs, sqrt
|
||||
real(dp) :: scale
|
||||
real(dp), parameter :: zero = 0.0_dp
|
||||
|
||||
scale = abs(a) + abs(b)
|
||||
if (scale == zero) then
|
||||
d2norm = zero
|
||||
else
|
||||
d2norm = scale*sqrt((a/scale)**2 + (b/scale)**2)
|
||||
end if
|
||||
|
||||
end function d2norm
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
subroutine localVEnqueue
|
||||
|
||||
! Store v into the circular buffer localV.
|
||||
|
||||
if (localPointer < localVecs) then
|
||||
localPointer = localPointer + 1
|
||||
else
|
||||
localPointer = 1
|
||||
localVQueueFull = .true.
|
||||
end if
|
||||
localV(:,localPointer) = v
|
||||
|
||||
end subroutine localVEnqueue
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
subroutine localVOrtho
|
||||
|
||||
! Perform local reorthogonalization of current v.
|
||||
|
||||
real(dp) :: d
|
||||
|
||||
if (localVQueueFull) then
|
||||
localOrthoLimit = localVecs
|
||||
else
|
||||
localOrthoLimit = localPointer
|
||||
end if
|
||||
|
||||
do localOrthoCount = 1, localOrthoLimit
|
||||
d = dot_product(v,localV(:,localOrthoCount))
|
||||
v = v - d * localV(:,localOrthoCount)
|
||||
end do
|
||||
|
||||
end subroutine localVOrtho
|
||||
|
||||
end subroutine LSMR
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
end module LSMRmodule
|
@ -1,360 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrblas.f90 (double precision)
|
||||
!
|
||||
! This file contains the following BLAS routines
|
||||
! dcopy, ddot, dnrm2, dscal
|
||||
! required by subroutines LSMR and Acheck.
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
!
|
||||
!! DCOPY copies a vector X to a vector Y.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
! The routine uses unrolled loops for increments equal to one.
|
||||
!
|
||||
! Modified:
|
||||
! 16 May 2005
|
||||
!
|
||||
! Author:
|
||||
! Jack Dongarra
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
!
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of elements in DX and DY.
|
||||
!
|
||||
! Input, real ( kind = 8 ) DX(*), the first vector.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries of DX.
|
||||
!
|
||||
! Output, real ( kind = 8 ) DY(*), the second vector.
|
||||
!
|
||||
! Input, integer INCY, the increment between successive entries of DY.
|
||||
|
||||
|
||||
subroutine dcopy(n,dx,incx,dy,incy)
|
||||
|
||||
implicit none
|
||||
! double precision dx(*),dy(*)
|
||||
real(4) dx(*),dy(*)
|
||||
integer i,incx,incy,ix,iy,m,n
|
||||
|
||||
if ( n <= 0 ) then
|
||||
return
|
||||
end if
|
||||
|
||||
if ( incx == 1 .and. incy == 1 ) then
|
||||
|
||||
m = mod ( n, 7 )
|
||||
|
||||
if ( m /= 0 ) then
|
||||
dy(1:m) = dx(1:m)
|
||||
end if
|
||||
|
||||
do i = m+1, n, 7
|
||||
dy(i) = dx(i)
|
||||
dy(i + 1) = dx(i + 1)
|
||||
dy(i + 2) = dx(i + 2)
|
||||
dy(i + 3) = dx(i + 3)
|
||||
dy(i + 4) = dx(i + 4)
|
||||
dy(i + 5) = dx(i + 5)
|
||||
dy(i + 6) = dx(i + 6)
|
||||
end do
|
||||
|
||||
else
|
||||
|
||||
if ( 0 <= incx ) then
|
||||
ix = 1
|
||||
else
|
||||
ix = ( -n + 1 ) * incx + 1
|
||||
end if
|
||||
|
||||
if ( 0 <= incy ) then
|
||||
iy = 1
|
||||
else
|
||||
iy = ( -n + 1 ) * incy + 1
|
||||
end if
|
||||
|
||||
do i = 1, n
|
||||
dy(iy) = dx(ix)
|
||||
ix = ix + incx
|
||||
iy = iy + incy
|
||||
end do
|
||||
end if
|
||||
return
|
||||
end subroutine dcopy
|
||||
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!
|
||||
!! DDOT forms the dot product of two vectors.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
! This routine uses unrolled loops for increments equal to one.
|
||||
!
|
||||
! Modified:
|
||||
! 16 May 2005
|
||||
!
|
||||
! Author:
|
||||
! Jack Dongarra
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of entries in the vectors.
|
||||
!
|
||||
! Input, real ( kind = 8 ) DX(*), the first vector.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries in DX.
|
||||
!
|
||||
! Input, real ( kind = 8 ) DY(*), the second vector.
|
||||
!
|
||||
! Input, integer INCY, the increment between successive entries in DY.
|
||||
!
|
||||
! Output, real ( kind = 8 ) DDOT, the sum of the product of the
|
||||
! corresponding entries of DX and DY.
|
||||
|
||||
|
||||
! double precision function ddot(n,dx,incx,dy,incy)
|
||||
real(4) function ddot(n,dx,incx,dy,incy)
|
||||
|
||||
implicit none
|
||||
! double precision dx(*),dy(*),dtemp
|
||||
real(4) dx(*),dy(*),dtemp
|
||||
integer i,incx,incy,ix,iy,m,n
|
||||
|
||||
ddot = 0.0d0
|
||||
dtemp = 0.0d0
|
||||
if ( n <= 0 ) then
|
||||
return
|
||||
end if
|
||||
|
||||
! Code for unequal increments or equal increments
|
||||
! not equal to 1.
|
||||
|
||||
if ( incx /= 1 .or. incy /= 1 ) then
|
||||
|
||||
if ( 0 <= incx ) then
|
||||
ix = 1
|
||||
else
|
||||
ix = ( - n + 1 ) * incx + 1
|
||||
end if
|
||||
|
||||
if ( 0 <= incy ) then
|
||||
iy = 1
|
||||
else
|
||||
iy = ( - n + 1 ) * incy + 1
|
||||
end if
|
||||
|
||||
do i = 1, n
|
||||
dtemp = dtemp + dx(ix) * dy(iy)
|
||||
ix = ix + incx
|
||||
iy = iy + incy
|
||||
end do
|
||||
|
||||
! Code for both increments equal to 1.
|
||||
|
||||
else
|
||||
|
||||
m = mod ( n, 5 )
|
||||
|
||||
do i = 1, m
|
||||
dtemp = dtemp + dx(i) * dy(i)
|
||||
end do
|
||||
|
||||
do i = m+1, n, 5
|
||||
dtemp = dtemp + dx(i)*dy(i) + dx(i+1)*dy(i+1) + dx(i+2)*dy(i+2) &
|
||||
+ dx(i+3)*dy(i+3) + dx(i+4)*dy(i+4)
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
ddot = dtemp
|
||||
return
|
||||
end function ddot
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!*****************************************************************************80
|
||||
!
|
||||
!! DNRM2 returns the euclidean norm of a vector.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
! DNRM2 ( X ) = sqrt ( X' * X )
|
||||
!
|
||||
! Modified:
|
||||
! 16 May 2005
|
||||
!
|
||||
! Author:
|
||||
! Sven Hammarling
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of entries in the vector.
|
||||
!
|
||||
! Input, real ( kind = 8 ) X(*), the vector whose norm is to be computed.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries of X.
|
||||
!
|
||||
! Output, real ( kind = 8 ) DNRM2, the Euclidean norm of X.
|
||||
!
|
||||
|
||||
! double precision function dnrm2 ( n, x, incx)
|
||||
real(4) function dnrm2 ( n, x, incx)
|
||||
implicit none
|
||||
integer ix,n,incx
|
||||
! double precision x(*), ssq,absxi,norm,scale
|
||||
real(4) x(*), ssq,absxi,norm,scale
|
||||
|
||||
if ( n < 1 .or. incx < 1 ) then
|
||||
norm = 0.d0
|
||||
else if ( n == 1 ) then
|
||||
norm = abs ( x(1) )
|
||||
else
|
||||
scale = 0.d0
|
||||
ssq = 1.d0
|
||||
|
||||
do ix = 1, 1 + ( n - 1 )*incx, incx
|
||||
if ( x(ix) /= 0.d0 ) then
|
||||
absxi = abs ( x(ix) )
|
||||
if ( scale < absxi ) then
|
||||
ssq = 1.d0 + ssq * ( scale / absxi )**2
|
||||
scale = absxi
|
||||
else
|
||||
ssq = ssq + ( absxi / scale )**2
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
norm = scale * sqrt ( ssq )
|
||||
end if
|
||||
|
||||
dnrm2 = norm
|
||||
return
|
||||
end function dnrm2
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! DSCAL scales a vector by a constant.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
!
|
||||
! Modified:
|
||||
! 08 April 1999
|
||||
!
|
||||
! Author:
|
||||
! Jack Dongarra
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of entries in the vector.
|
||||
!
|
||||
! Input, real ( kind = 8 ) SA, the multiplier.
|
||||
!
|
||||
! Input/output, real ( kind = 8 ) X(*), the vector to be scaled.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries of X.
|
||||
!
|
||||
|
||||
subroutine dscal(n,sa,x,incx)
|
||||
|
||||
implicit none
|
||||
|
||||
integer i
|
||||
integer incx
|
||||
integer ix
|
||||
integer m
|
||||
integer n
|
||||
!double precision sa
|
||||
!double precision x(*)
|
||||
|
||||
real(4) sa
|
||||
real(4) x(*)
|
||||
if ( n <= 0 ) then
|
||||
return
|
||||
else if ( incx == 1 ) then
|
||||
m = mod ( n, 5 )
|
||||
x(1:m) = sa * x(1:m)
|
||||
|
||||
do i = m+1, n, 5
|
||||
x(i) = sa * x(i)
|
||||
x(i+1) = sa * x(i+1)
|
||||
x(i+2) = sa * x(i+2)
|
||||
x(i+3) = sa * x(i+3)
|
||||
x(i+4) = sa * x(i+4)
|
||||
end do
|
||||
else
|
||||
if ( 0 <= incx ) then
|
||||
ix = 1
|
||||
else
|
||||
ix = ( - n + 1 ) * incx + 1
|
||||
end if
|
||||
|
||||
do i = 1, n
|
||||
x(ix) = sa * x(ix)
|
||||
ix = ix + incx
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
return
|
||||
end subroutine dscal
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
@ -1,41 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrblasInterface.f90
|
||||
!
|
||||
! BLAS1 Interfaces: ddot dnrm2 dscal
|
||||
!
|
||||
! Maintained by Michael Saunders <saunders@stanford.edu>.
|
||||
!
|
||||
! 19 Dec 2008: lsqrblasInterface module implemented.
|
||||
! Metcalf and Reid recommend putting interfaces in a module.
|
||||
! 16 Jul 2010: LSMR version derived from LSQR equivalent.
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
module lsmrblasInterface
|
||||
|
||||
implicit none
|
||||
public :: ddot, dnrm2, dscal
|
||||
|
||||
interface ! Level 1 BLAS
|
||||
function ddot (n,dx,incx,dy,incy)
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: n,incx,incy
|
||||
real(dp), intent(in) :: dx(*),dy(*)
|
||||
real(dp) :: ddot
|
||||
end function ddot
|
||||
|
||||
function dnrm2 (n,dx,incx)
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: n,incx
|
||||
real(dp), intent(in) :: dx(*)
|
||||
real(dp) :: dnrm2
|
||||
end function dnrm2
|
||||
|
||||
subroutine dscal (n,sa,x,incx)
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: n,incx
|
||||
real(dp), intent(in) :: sa
|
||||
real(dp), intent(inout) :: x(*)
|
||||
end subroutine dscal
|
||||
end interface
|
||||
|
||||
end module lsmrblasInterface
|
@ -1,616 +0,0 @@
|
||||
! CODE FOR SURFACE WAVE TOMOGRAPHY USING DISPERSION MEASUREMENTS
|
||||
! VERSION:
|
||||
! 1.0
|
||||
! AUTHOR:
|
||||
! HONGJIAN FANG. fanghj@mail.ustc.edu.cn
|
||||
! PURPOSE:
|
||||
! DIRECTLY INVERT SURFACE WAVE DISPERSION MEASUREMENTS FOR 3-D
|
||||
! STUCTURE WITHOUT THE INTERMEDIATE STEP OF CONSTUCTION THE PHASE
|
||||
! OR GROUP VELOCITY MAPS.
|
||||
! REFERENCE:
|
||||
! Fang, H., Yao, H., Zhang, H., Huang, Y. C., & van der Hilst, R. D.
|
||||
! (2015). Direct inversion of surface wave dispersion for
|
||||
! three-dimensional shallow crustal structure based on ray tracing:
|
||||
! methodology and application. Geophysical Journal International,
|
||||
! 201(3), 1251-1263.
|
||||
! HISTORY:
|
||||
! 2015/01/31 START TO REORGONIZE THE MESSY CODE
|
||||
!
|
||||
|
||||
program SurfTomo
|
||||
use lsmrModule, only:lsmr
|
||||
use lsmrblasInterface, only : dnrm2
|
||||
implicit none
|
||||
|
||||
! VARIABLE DEFINE
|
||||
|
||||
character inputfile*80
|
||||
character logfile*100
|
||||
character outmodel*100
|
||||
character outsyn*100
|
||||
logical ex
|
||||
character dummy*40
|
||||
character datafile*80
|
||||
|
||||
integer nx,ny,nz
|
||||
real goxd,gozd
|
||||
real dvxd,dvzd
|
||||
integer nsrc,nrc
|
||||
real weight,weight0
|
||||
real damp
|
||||
real minthk
|
||||
integer kmax,kmaxRc,kmaxRg,kmaxLc,kmaxLg
|
||||
real*8,dimension(:),allocatable:: tRc,tRg,tLc,tLg
|
||||
real,dimension(:),allocatable:: depz
|
||||
integer itn
|
||||
integer nout
|
||||
integer localSize
|
||||
real mean,std_devs,balances,balanceb
|
||||
integer msurf
|
||||
real,parameter:: tolr=1e-4
|
||||
real,dimension(:),allocatable:: obst,dsyn,cbst,wt,dtres,dist,datweight
|
||||
real,dimension(:),allocatable:: pvall,depRp,pvRp
|
||||
real sta1_lat,sta1_lon,sta2_lat,sta2_lon
|
||||
real dist1
|
||||
integer dall
|
||||
integer istep
|
||||
real,parameter :: pi=3.1415926535898
|
||||
integer checkstat
|
||||
integer ii,jj,kk
|
||||
real, dimension (:,:), allocatable :: scxf,sczf
|
||||
real, dimension (:,:,:), allocatable :: rcxf,rczf
|
||||
integer,dimension(:,:),allocatable::wavetype,igrt,nrc1
|
||||
integer,dimension(:),allocatable::nsrc1,knum1
|
||||
integer,dimension(:,:),allocatable::periods
|
||||
real,dimension(:),allocatable::rw
|
||||
integer,dimension(:),allocatable::iw,col
|
||||
real,dimension(:),allocatable::dv,norm
|
||||
real,dimension(:,:,:),allocatable::vsf
|
||||
real,dimension(:,:,:),allocatable::vsftrue
|
||||
character strf
|
||||
integer veltp,wavetp
|
||||
real velvalue
|
||||
integer knum,knumo,err
|
||||
integer istep1,istep2
|
||||
integer period
|
||||
integer knumi,srcnum,count1
|
||||
integer HorizonType,VerticalType
|
||||
character line*200
|
||||
integer iter,maxiter
|
||||
integer maxnar
|
||||
real acond
|
||||
real anorm
|
||||
real arnorm
|
||||
real rnorm
|
||||
real xnorm
|
||||
character str1
|
||||
real atol,btol
|
||||
real conlim
|
||||
integer istop
|
||||
integer itnlim
|
||||
integer lenrw,leniw
|
||||
integer nar,nar_tmp,nars
|
||||
integer count3,nvz,nvx
|
||||
integer m,maxvp,n
|
||||
integer i,j,k
|
||||
real Minvel,MaxVel
|
||||
real spfra
|
||||
real noiselevel
|
||||
integer ifsyn
|
||||
integer writepath
|
||||
real averdws
|
||||
real maxnorm
|
||||
real threshold,threshold0
|
||||
|
||||
! OPEN FILES FIRST TO OUTPUT THE PROCESS
|
||||
open(34,file='IterVel.out')
|
||||
nout=36
|
||||
open(nout,file='lsmr.txt')
|
||||
|
||||
! OUTPUT PROGRAM INFOMATION
|
||||
write(*,*)
|
||||
write(*,*),' S U R F T O M O'
|
||||
write(*,*),'PLEASE contact Hongjain Fang &
|
||||
(fanghj@mail.ustc.edu.cn) if you find any bug'
|
||||
write(*,*)
|
||||
|
||||
! READ INPUT FILE
|
||||
if (iargc() < 1) then
|
||||
write(*,*) 'input file [SurfTomo.in(default)]:'
|
||||
read(*,'(a)') inputfile
|
||||
if (len_trim(inputfile) <=1 ) then
|
||||
inputfile = 'SurfTomo.in'
|
||||
else
|
||||
inputfile = inputfile(1:len_trim(inputfile))
|
||||
endif
|
||||
else
|
||||
call getarg(1,inputfile)
|
||||
endif
|
||||
inquire(file = inputfile, exist = ex)
|
||||
if (.not. ex) stop 'unable to open the inputfile'
|
||||
|
||||
open(10,file=inputfile,status='old')
|
||||
read(10,'(a30)')dummy
|
||||
read(10,'(a30)')dummy
|
||||
read(10,'(a30)')dummy
|
||||
read(10,*)datafile
|
||||
read(10,*) nx,ny,nz
|
||||
read(10,*) goxd,gozd
|
||||
read(10,*) dvxd,dvzd
|
||||
read(10,*) nsrc
|
||||
read(10,*) weight0,damp
|
||||
read(10,*) minthk
|
||||
read(10,*) Minvel,Maxvel
|
||||
read(10,*) maxiter
|
||||
read(10,*) spfra
|
||||
read(10,*) kmaxRc
|
||||
write(*,*) 'model origin:latitude,longitue'
|
||||
write(*,'(2f10.4)') goxd,gozd
|
||||
write(*,*) 'grid spacing:latitude,longitue'
|
||||
write(*,'(2f10.4)') dvxd,dvzd
|
||||
write(*,*) 'model dimension:nx,ny,nz'
|
||||
write(*,'(3i5)') nx,ny,nz
|
||||
write(logfile,'(a,a)')trim(inputfile),'.log'
|
||||
open(66,file=logfile)
|
||||
write(66,*)
|
||||
write(66,*),' S U R F T O M O'
|
||||
write(66,*),'PLEASE contact Hongjain Fang &
|
||||
(fanghj@mail.ustc.edu.cn) if you find any bug'
|
||||
write(66,*)
|
||||
write(66,*) 'model origin:latitude,longitue'
|
||||
write(66,'(2f10.4)') goxd,gozd
|
||||
write(66,*) 'grid spacing:latitude,longitue'
|
||||
write(66,'(2f10.4)') dvxd,dvzd
|
||||
write(66,*) 'model dimension:nx,ny,nz'
|
||||
write(66,'(3i5)') nx,ny,nz
|
||||
if(kmaxRc.gt.0)then
|
||||
allocate(tRc(kmaxRc),&
|
||||
stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tRc(i),i=1,kmaxRc)
|
||||
write(*,*)'Rayleigh wave phase velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tRc(i),i=1,kmaxRc)
|
||||
write(66,*)'Rayleigh wave phase velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tRc(i),i=1,kmaxRc)
|
||||
endif
|
||||
read(10,*)kmaxRg
|
||||
if(kmaxRg.gt.0)then
|
||||
allocate(tRg(kmaxRg), stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tRg(i),i=1,kmaxRg)
|
||||
write(*,*)'Rayleigh wave group velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tRg(i),i=1,kmaxRg)
|
||||
write(66,*)'Rayleigh wave group velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tRg(i),i=1,kmaxRg)
|
||||
endif
|
||||
read(10,*)kmaxLc
|
||||
if(kmaxLc.gt.0)then
|
||||
allocate(tLc(kmaxLc), stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tLc(i),i=1,kmaxLc)
|
||||
write(*,*)'Love wave phase velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tLc(i),i=1,kmaxLc)
|
||||
write(66,*)'Love wave phase velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tLc(i),i=1,kmaxLc)
|
||||
endif
|
||||
read(10,*)kmaxLg
|
||||
if(kmaxLg.gt.0)then
|
||||
allocate(tLg(kmaxLg), stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tLg(i),i=1,kmaxLg)
|
||||
write(*,*)'Love wave group velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tLg(i),i=1,kmaxLg)
|
||||
write(66,*)'Love wave group velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tLg(i),i=1,kmaxLg)
|
||||
endif
|
||||
read(10,*)ifsyn
|
||||
read(10,*)noiselevel
|
||||
read(10,*) threshold0
|
||||
close(10)
|
||||
nrc=nsrc
|
||||
kmax=kmaxRc+kmaxRg+kmaxLc+kmaxLg
|
||||
|
||||
! READ MEASUREMENTS
|
||||
open(unit=87,file=datafile,status='old')
|
||||
allocate(scxf(nsrc,kmax),sczf(nsrc,kmax),&
|
||||
rcxf(nrc,nsrc,kmax),rczf(nrc,nsrc,kmax),stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate'
|
||||
endif
|
||||
allocate(periods(nsrc,kmax),wavetype(nsrc,kmax),&
|
||||
nrc1(nsrc,kmax),nsrc1(kmax),knum1(kmax),&
|
||||
igrt(nsrc,kmax),stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate'
|
||||
endif
|
||||
allocate(obst(nrc*nsrc*kmax),dist(nrc*nsrc*kmax),&
|
||||
stat=checkstat)
|
||||
allocate(pvall(nrc*nsrc*kmax),depRp(nrc*nsrc*kmax),&
|
||||
pvRp(nrc*nsrc*kmax),stat=checkstat)
|
||||
IF(checkstat > 0)THEN
|
||||
write(6,*)'error with allocate'
|
||||
ENDIF
|
||||
istep=0
|
||||
istep2=0
|
||||
dall=0
|
||||
knumo=12345
|
||||
knum=0
|
||||
istep1=0
|
||||
do
|
||||
read(87,'(a)',iostat=err) line
|
||||
if(err.eq.0) then
|
||||
if(line(1:1).eq.'#') then
|
||||
read(line,*) str1,sta1_lat,sta1_lon,period,wavetp,veltp
|
||||
if(wavetp.eq.2.and.veltp.eq.0) knum=period
|
||||
if(wavetp.eq.2.and.veltp.eq.1) knum=kmaxRc+period
|
||||
if(wavetp.eq.1.and.veltp.eq.0) knum=kmaxRg+kmaxRc+period
|
||||
if(wavetp.eq.1.and.veltp.eq.1) knum=kmaxLc+kmaxRg+&
|
||||
kmaxRc+period
|
||||
if(knum.ne.knumo) then
|
||||
istep=0
|
||||
istep2=istep2+1
|
||||
endif
|
||||
istep=istep+1
|
||||
istep1=0
|
||||
sta1_lat=(90.0-sta1_lat)*pi/180.0
|
||||
sta1_lon=sta1_lon*pi/180.0
|
||||
scxf(istep,knum)=sta1_lat
|
||||
sczf(istep,knum)=sta1_lon
|
||||
periods(istep,knum)=period
|
||||
wavetype(istep,knum)=wavetp
|
||||
igrt(istep,knum)=veltp
|
||||
nsrc1(knum)=istep
|
||||
knum1(istep2)=knum
|
||||
knumo=knum
|
||||
else
|
||||
read(line,*) sta2_lat,sta2_lon,velvalue
|
||||
istep1=istep1+1
|
||||
dall=dall+1
|
||||
sta2_lat=(90.0-sta2_lat)*pi/180.0
|
||||
sta2_lon=sta2_lon*pi/180.0
|
||||
rcxf(istep1,istep,knum)=sta2_lat
|
||||
rczf(istep1,istep,knum)=sta2_lon
|
||||
call delsph(sta1_lat,sta1_lon,sta2_lat,sta2_lon,dist1)
|
||||
dist(dall)=dist1
|
||||
obst(dall)=dist1/velvalue
|
||||
pvall(dall)=velvalue
|
||||
nrc1(istep,knum)=istep1
|
||||
endif
|
||||
else
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
close(87)
|
||||
allocate(depz(nz), stat=checkstat)
|
||||
maxnar = dall*nx*ny*nz*spfra!sparsity fraction
|
||||
maxvp = (nx-2)*(ny-2)*(nz-1)
|
||||
allocate(dv(maxvp), stat=checkstat)
|
||||
allocate(norm(maxvp), stat=checkstat)
|
||||
allocate(vsf(nx,ny,nz), stat=checkstat)
|
||||
allocate(vsftrue(nx,ny,nz), stat=checkstat)
|
||||
|
||||
allocate(rw(maxnar), stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate: real rw'
|
||||
endif
|
||||
allocate(iw(2*maxnar+1), stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate: integer iw'
|
||||
endif
|
||||
allocate(col(maxnar), stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate: integer iw'
|
||||
endif
|
||||
allocate(cbst(dall+maxvp),dsyn(dall),datweight(dall),wt(dall+maxvp),dtres(dall+maxvp),&
|
||||
stat=checkstat)
|
||||
|
||||
! MEASUREMENTS STATISTICS AND READ INITIAL MODEL
|
||||
write(*,'(a,i7)') 'Number of all measurements',dall
|
||||
|
||||
open(10,file='MOD',status='old')
|
||||
read(10,*) (depz(i),i=1,nz)
|
||||
do k = 1,nz
|
||||
do j = 1,ny
|
||||
read(10,*)(vsf(i,j,k),i=1,nx)
|
||||
enddo
|
||||
enddo
|
||||
close(10)
|
||||
write(*,*) 'grid points in depth direction:(km)'
|
||||
write(*,'(50f6.2)') depz
|
||||
|
||||
|
||||
|
||||
! CHECKERBOARD TEST
|
||||
if (ifsyn == 1) then
|
||||
write(*,*) 'Checkerboard Resolution Test Begin'
|
||||
vsftrue = vsf
|
||||
|
||||
open(11,file='MOD.true',status='old')
|
||||
do k = 1,nz
|
||||
do j = 1,ny
|
||||
read(11,*) (vsftrue(i,j,k),i=1,nx)
|
||||
enddo
|
||||
enddo
|
||||
close(11)
|
||||
|
||||
call synthetic(nx,ny,nz,maxvp,vsftrue,obst,&
|
||||
goxd,gozd,dvxd,dvzd,kmaxRc,kmaxRg,kmaxLc,kmaxLg,&
|
||||
tRc,tRg,tLc,tLg,wavetype,igrt,periods,depz,minthk,&
|
||||
scxf,sczf,rcxf,rczf,nrc1,nsrc1,knum1,kmax,&
|
||||
nsrc,nrc,noiselevel)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
! ITERATE UNTILL CONVERGE
|
||||
writepath = 0
|
||||
do iter = 1,maxiter
|
||||
iw = 0
|
||||
rw = 0.0
|
||||
col = 0
|
||||
|
||||
! COMPUTE SENSITIVITY MATRIX
|
||||
if (iter == maxiter) then
|
||||
writepath = 1
|
||||
open(40,file='raypath.out')
|
||||
endif
|
||||
write(*,*) 'computing sensitivity matrix...'
|
||||
call CalSurfG(nx,ny,nz,maxvp,vsf,iw,rw,col,dsyn,&
|
||||
goxd,gozd,dvxd,dvzd,kmaxRc,kmaxRg,kmaxLc,kmaxLg,&
|
||||
tRc,tRg,tLc,tLg,wavetype,igrt,periods,depz,minthk,&
|
||||
scxf,sczf,rcxf,rczf,nrc1,nsrc1,knum1,kmax,&
|
||||
nsrc,nrc,nar,writepath)
|
||||
|
||||
do i = 1,dall
|
||||
cbst(i) = obst(i) - dsyn(i)
|
||||
enddo
|
||||
|
||||
threshold = threshold0+(maxiter/2-iter)/3*0.5
|
||||
do i = 1,dall
|
||||
datweight(i) = 1.0
|
||||
if(abs(cbst(i)) > threshold) then
|
||||
datweight(i) = exp(-(abs(cbst(i))-threshold))
|
||||
endif
|
||||
cbst(i) = cbst(i)*datweight(i)
|
||||
enddo
|
||||
|
||||
do i = 1,nar
|
||||
rw(i) = rw(i)*datweight(iw(1+i))
|
||||
enddo
|
||||
|
||||
norm=0
|
||||
do i=1,nar
|
||||
norm(col(i))=norm(col(i))+abs(rw(i))
|
||||
enddo
|
||||
averdws=0
|
||||
maxnorm=0
|
||||
do i=1,maxvp
|
||||
averdws = averdws+norm(i)
|
||||
if(norm(i)>maxnorm) maxnorm=norm(i)
|
||||
enddo
|
||||
averdws=averdws/maxvp
|
||||
write(66,*)'Maximum and Average DWS values:',maxnorm,averdws
|
||||
write(66,*)'Threshold is:',threshold
|
||||
|
||||
! WRITE OUT RESIDUAL FOR THE FIRST AND LAST ITERATION
|
||||
if(iter.eq.1) then
|
||||
open(88,file='residualFirst.dat')
|
||||
do i=1,dall
|
||||
write(88,*) dist(i),dsyn(i),obst(i), &
|
||||
dsyn(i)*datweight(i),obst(i)*datweight(i),datweight(i)
|
||||
enddo
|
||||
close(88)
|
||||
endif
|
||||
if(iter.eq.maxiter) then
|
||||
open(88,file='residualLast.dat')
|
||||
do i=1,dall
|
||||
write(88,*) dist(i),dsyn(i),obst(i), &
|
||||
dsyn(i)*datweight(i),obst(i)*datweight(i),datweight(i)
|
||||
enddo
|
||||
close(88)
|
||||
endif
|
||||
|
||||
|
||||
! ADDING REGULARIZATION TERM
|
||||
weight=dnrm2(dall,cbst,1)**2/dall*weight0
|
||||
nar_tmp=nar
|
||||
nars=0
|
||||
|
||||
count3=0
|
||||
nvz=ny-2
|
||||
nvx=nx-2
|
||||
do k=1,nz-1
|
||||
do j=1,nvz
|
||||
do i=1,nvx
|
||||
if(i==1.or.i==nvx.or.j==1.or.j==nvz.or.k==1.or.k==nz-1)then
|
||||
count3=count3+1
|
||||
col(nar+1)=(k-1)*nvz*nvx+(j-1)*nvx+i
|
||||
rw(nar+1)=2.0*weight
|
||||
iw(1+nar+1)=dall+count3
|
||||
cbst(dall+count3)=0
|
||||
nar=nar+1
|
||||
else
|
||||
count3=count3+1
|
||||
col(nar+1)=(k-1)*nvz*nvx+(j-1)*nvx+i
|
||||
rw(nar+1)=6.0*weight
|
||||
iw(1+nar+1)=dall+count3
|
||||
rw(nar+2)=-1.0*weight
|
||||
iw(1+nar+2)=dall+count3
|
||||
col(nar+2)=(k-1)*nvz*nvx+(j-1)*nvx+i-1
|
||||
rw(nar+3)=-1.0*weight
|
||||
iw(1+nar+3)=dall+count3
|
||||
col(nar+3)=(k-1)*nvz*nvx+(j-1)*nvx+i+1
|
||||
rw(nar+4)=-1.0*weight
|
||||
iw(1+nar+4)=dall+count3
|
||||
col(nar+4)=(k-1)*nvz*nvx+(j-2)*nvx+i
|
||||
rw(nar+5)=-1.0*weight
|
||||
iw(1+nar+5)=dall+count3
|
||||
col(nar+5)=(k-1)*nvz*nvx+j*nvx+i
|
||||
rw(nar+6)=-1.0*weight
|
||||
iw(1+nar+6)=dall+count3
|
||||
col(nar+6)=(k-2)*nvz*nvx+(j-1)*nvx+i
|
||||
rw(nar+7)=-1.0*weight
|
||||
iw(1+nar+7)=dall+count3
|
||||
col(nar+7)=k*nvz*nvx+(j-1)*nvx+i
|
||||
cbst(dall+count3)=0
|
||||
nar=nar+7
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
m = dall + count3
|
||||
n = maxvp
|
||||
|
||||
iw(1)=nar
|
||||
do i=1,nar
|
||||
iw(1+nar+i)=col(i)
|
||||
enddo
|
||||
if (nar > maxnar) stop 'increase sparsity fraction(spfra)'
|
||||
|
||||
! CALLING IRLS TO SOLVE THE PROBLEM
|
||||
|
||||
leniw = 2*nar+1
|
||||
lenrw = nar
|
||||
dv = 0
|
||||
atol = 1e-3
|
||||
btol = 1e-3
|
||||
conlim = 1200
|
||||
itnlim = 1000
|
||||
istop = 0
|
||||
anorm = 0.0
|
||||
acond = 0.0
|
||||
arnorm = 0.0
|
||||
xnorm = 0.0
|
||||
localSize = n/4
|
||||
|
||||
call LSMR(m, n, leniw, lenrw,iw,rw,cbst, damp,&
|
||||
atol, btol, conlim, itnlim, localSize, nout,&
|
||||
dv, istop, itn, anorm, acond, rnorm, arnorm, xnorm)
|
||||
if(istop==3) print*,'istop = 3, large condition number'
|
||||
|
||||
|
||||
mean = sum(cbst(1:dall))/dall
|
||||
std_devs = sqrt(sum(cbst(1:dall)**2)/dall - mean**2)
|
||||
write(*,'(i2,a)'),iter,'th iteration...'
|
||||
write(*,'(a,f7.3)'),'weight is:',weight
|
||||
write(*,'(a,f8.1,a,f8.2,a,f8.3)'),'mean,std_devs and chi sqrue of &
|
||||
residual: ',mean*1000,'ms ',1000*std_devs,'ms ',&
|
||||
dnrm2(dall,cbst,1)**2/sqrt(dall)
|
||||
write(66,'(i2,a)'),iter,'th iteration...'
|
||||
write(66,'(a,f7.3)'),'weight is:',weight
|
||||
write(66,'(a,f8.1,a,f8.2,a,f8.3)'),'mean,std_devs and chi sqrue of &
|
||||
residual: ',mean*1000,'ms ',1000*std_devs,'ms ',&
|
||||
dnrm2(dall,cbst,1)**2/sqrt(dall)
|
||||
|
||||
write(*,'(a,2f7.4)'),'min and max velocity variation ',&
|
||||
minval(dv),maxval(dv)
|
||||
write(66,'(a,2f7.4)'),'min and max velocity variation ',&
|
||||
minval(dv),maxval(dv)
|
||||
|
||||
do k=1,nz-1
|
||||
do j=1,ny-2
|
||||
do i=1,nx-2
|
||||
if(dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i).ge.0.500) then
|
||||
dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i)=0.500
|
||||
endif
|
||||
if(dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i).le.-0.500) then
|
||||
dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i)=-0.500
|
||||
endif
|
||||
vsf(i+1,j+1,k)=vsf(i+1,j+1,k)+dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i)
|
||||
if(vsf(i+1,j+1,k).lt.Minvel) vsf(i+1,j+1,k)=Minvel
|
||||
if(vsf(i+1,j+1,k).gt.Maxvel) vsf(i+1,j+1,k)=Maxvel
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
write(34,*)',OUTPUT S VELOCITY AT ITERATION',iter
|
||||
do k=1,nz
|
||||
do j=1,ny
|
||||
write(34,'(100f7.3)') (vsf(i,j,k),i=1,nx)
|
||||
enddo
|
||||
enddo
|
||||
write(34,*)',OUTPUT DWS AT ITERATION',iter
|
||||
do k=1,nz-1
|
||||
do j=2,ny-1
|
||||
write(34,'(100f8.1)') (norm((k-1)*(ny-2)*(nx-2)+(j-2)*(nx-2)+i-1),i=2,nx-1)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
enddo !end iteration
|
||||
|
||||
! OUTPUT THE VELOCITY MODEL
|
||||
|
||||
write(*,*),'Program finishes successfully'
|
||||
write(66,*),'Program finishes successfully'
|
||||
|
||||
if(ifsyn == 1) then
|
||||
open(65,file='Vs_model.real')
|
||||
write(outsyn,'(a,a)') trim(inputfile),'Syn.dat'
|
||||
open(63,file=outsyn)
|
||||
do k=1,nz-1
|
||||
do j=1,ny-2
|
||||
do i=1,nx-2
|
||||
write(65,'(5f8.4)') gozd+(j-1)*dvzd,goxd-(i-1)*dvxd,depz(k),vsftrue(i,j,k)
|
||||
write(63,'(5f8.4)') gozd+(j-1)*dvzd,goxd-(i-1)*dvxd,depz(k),vsf(i,j,k)
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
close(65)
|
||||
close(63)
|
||||
write(*,*),'Output True velocity model &
|
||||
to Vs_model.real'
|
||||
write(*,*),'Output inverted shear velocity model &
|
||||
to ',outsyn
|
||||
write(66,*),'Output True velocity model &
|
||||
to Vs_model.real'
|
||||
write(66,*),'Output inverted shear velocity model &
|
||||
to ',outsyn
|
||||
else
|
||||
write(outmodel,'(a,a)') trim(inputfile),'Measure.dat'
|
||||
open(64,file=outmodel)
|
||||
do k=1,nz-1
|
||||
do j=1,ny-2
|
||||
do i=1,nx-2
|
||||
write(64,'(5f8.4)') gozd+(j-1)*dvzd,goxd-(i-1)*dvxd,depz(k),vsf(i,j,k)
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
close(64)
|
||||
write(*,*),'Output inverted shear velocity model &
|
||||
to ',outmodel
|
||||
write(66,*),'Output inverted shear velocity model &
|
||||
to ',outmodel
|
||||
endif
|
||||
|
||||
close(34)
|
||||
close(40)
|
||||
close(nout) !close lsmr.txt
|
||||
close(66) !close surf_tomo.log
|
||||
deallocate(obst)
|
||||
deallocate(dsyn)
|
||||
deallocate(dist)
|
||||
deallocate(depz)
|
||||
deallocate(scxf,sczf)
|
||||
deallocate(rcxf,rczf)
|
||||
deallocate(wavetype,igrt,nrc1)
|
||||
deallocate(nsrc1,knum1,periods)
|
||||
deallocate(rw)
|
||||
deallocate(iw,col)
|
||||
deallocate(cbst,wt,dtres,datweight)
|
||||
deallocate(dv)
|
||||
deallocate(norm)
|
||||
deallocate(vsf)
|
||||
deallocate(vsftrue)
|
||||
if(kmaxRc.gt.0) then
|
||||
deallocate(tRc)
|
||||
endif
|
||||
if(kmaxRg.gt.0) then
|
||||
deallocate(tRg)
|
||||
endif
|
||||
if(kmaxLc.gt.0) then
|
||||
deallocate(tLc)
|
||||
endif
|
||||
if(kmaxLg.gt.0) then
|
||||
deallocate(tLg)
|
||||
endif
|
||||
|
||||
end program
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,25 +0,0 @@
|
||||
CMD = DSurfTomo
|
||||
FC = gfortran
|
||||
FFLAGS = -O3 -ffixed-line-length-none -ffloat-store\
|
||||
-W -fbounds-check -m64 -mcmodel=medium
|
||||
F90SRCS = lsmrDataModule.f90 lsmrblasInterface.f90 \
|
||||
lsmrblas.f90 lsmrModule.f90 delsph.f90\
|
||||
forwardstep.f90 forwardtrans.f90 split.f90 merge1.f90\
|
||||
invtrans3d.f90 inversetrans.f90 aprod.f90\
|
||||
haar.f90 waveletD8.f90 inversestep.f90\
|
||||
gaussian.f90 main.f90
|
||||
FSRCS = surfdisp96.f
|
||||
OBJS = $(F90SRCS:%.f90=%.o) $(FSRCS:%.f=%.o) CalSurfG.o wavelettrans3domp.o
|
||||
all:$(CMD)
|
||||
$(CMD):$(OBJS)
|
||||
$(FC) -fopenmp $^ -o $@
|
||||
CalSurfG.o:CalSurfG.f90
|
||||
$(FC) -fopenmp $(FFLAGS) -c $< -o $@
|
||||
wavelettrans3domp.o: wavelettrans3domp.f90
|
||||
$(FC) -fopenmp $(FFLAGS) -c $< -o $@
|
||||
%.o: %.f90
|
||||
$(FC) $(FFLAGS) -c $(@F:.o=.f90) -o $@
|
||||
%.o: %.f
|
||||
$(FC) $(FFLAGS) -c $(@F:.o=.f) -o $@
|
||||
clean:
|
||||
rm *.o *.mod $(CMD)
|
@ -1,60 +0,0 @@
|
||||
!c--- This file is from hypoDD by Felix Waldhauser ---------
|
||||
!c-------------------------Modified by Haijiang Zhang-------
|
||||
!c Multiply a matrix by a vector
|
||||
!c Version for use with sparse matrix specified by
|
||||
!c output of subroutine sparse for use with LSQR
|
||||
|
||||
subroutine aprod(mode, m, n, x, y, leniw, lenrw, iw, rw)
|
||||
|
||||
implicit none
|
||||
|
||||
!c Parameters:
|
||||
integer mode ! ==1: Compute y = y + a*x
|
||||
! y is altered without changing x
|
||||
! ==2: Compute x = x + a(transpose)*y
|
||||
! x is altered without changing y
|
||||
integer m, n ! Row and column dimensions of a
|
||||
real x(n), y(m) ! Input vectors
|
||||
integer :: leniw
|
||||
integer lenrw
|
||||
integer iw(leniw) ! Integer work vector containing:
|
||||
! iw[1] Number of non-zero elements in a
|
||||
! iw[2:iw[1]+1] Row indices of non-zero elements
|
||||
! iw[iw[1]+2:2*iw[1]+1] Column indices
|
||||
real rw(lenrw) ! [1..iw[1]] Non-zero elements of a
|
||||
|
||||
!c Local variables:
|
||||
integer i1
|
||||
integer j1
|
||||
integer k
|
||||
integer kk
|
||||
|
||||
!c set the ranges the indices in vector iw
|
||||
|
||||
kk=iw(1)
|
||||
i1=1
|
||||
j1=kk+1
|
||||
|
||||
!c main iteration loop
|
||||
|
||||
do k = 1,kk
|
||||
|
||||
if (mode.eq.1) then
|
||||
|
||||
!c compute y = y + a*x
|
||||
|
||||
y(iw(i1+k)) = y(iw(i1+k)) + rw(k)*x(iw(j1+k))
|
||||
|
||||
else
|
||||
|
||||
!c compute x = x + a(transpose)*y
|
||||
|
||||
x(iw(j1+k)) = x(iw(j1+k)) + rw(k)*y(iw(i1+k))
|
||||
|
||||
endif
|
||||
enddo
|
||||
|
||||
! 100 continue
|
||||
|
||||
return
|
||||
end
|
@ -1,28 +0,0 @@
|
||||
subroutine delsph(flat1,flon1,flat2,flon2,del)
|
||||
implicit none
|
||||
real,parameter:: R=6371.0
|
||||
REAL,parameter:: pi=3.1415926535898
|
||||
real flat1,flat2
|
||||
real flon1,flon2
|
||||
real del
|
||||
|
||||
real dlat
|
||||
real dlon
|
||||
real lat1
|
||||
real lat2
|
||||
real a
|
||||
real c
|
||||
|
||||
|
||||
!dlat=(flat2-flat1)*pi/180
|
||||
!dlon=(flon2-flon1)*pi/180
|
||||
!lat1=flat1*pi/180
|
||||
!lat2=flat2*pi/180
|
||||
dlat=flat2-flat1
|
||||
dlon=flon2-flon1
|
||||
lat1=pi/2-flat1
|
||||
lat2=pi/2-flat2
|
||||
a=sin(dlat/2)*sin(dlat/2)+sin(dlon/2)*sin(dlon/2)*cos(lat1)*cos(lat2)
|
||||
c=2*atan2(sqrt(a),sqrt(1-a))
|
||||
del=R*c
|
||||
end subroutine
|
@ -1,26 +0,0 @@
|
||||
subroutine forwardstep(vec,n)
|
||||
implicit none
|
||||
integer n
|
||||
real vec(n)
|
||||
|
||||
integer half, k, j
|
||||
half=n/2!changed to more than one
|
||||
do k=1,half
|
||||
vec(k)=vec(k)+sqrt(3.0)*vec(half+k)
|
||||
end do
|
||||
vec(half+1)=vec(half+1)-sqrt(3.0)/4.0*vec(1)- &
|
||||
(sqrt(3.0)-2)/4.0*vec(half)
|
||||
do k=1,half-1
|
||||
vec(half+k+1)=vec(half+k+1)-sqrt(3.0)/4.0*vec(k+1)- &
|
||||
(sqrt(3.0)-2)/4.0*vec(k)
|
||||
end do
|
||||
do k=1,half-1
|
||||
vec(k)=vec(k)-vec(half+k+1)
|
||||
end do
|
||||
vec(half)=vec(half)-vec(half+1)
|
||||
|
||||
do k=1,half
|
||||
vec(k)=(sqrt(3.0)-1)/sqrt(2.0)*vec(k)
|
||||
vec(half+k)=(sqrt(3.0)+1)/sqrt(2.0)*vec(half+k)
|
||||
end do
|
||||
end subroutine
|
@ -1,47 +0,0 @@
|
||||
subroutine forwardtrans(vec,n,mxl,tp)
|
||||
implicit none
|
||||
integer n,mxl,tp
|
||||
real vec(n)
|
||||
integer i,j
|
||||
integer forward
|
||||
i=n
|
||||
if (tp == 1) then
|
||||
forward=0
|
||||
do while(i.ge.n/(2**mxl))
|
||||
call split(vec,i)
|
||||
call predict(vec,i,forward)
|
||||
call update(vec,i,forward)
|
||||
call normalizationf(vec,i)
|
||||
i=i/2
|
||||
enddo
|
||||
endif
|
||||
|
||||
if (tp == 2) then
|
||||
do while(i.ge.n/(2**mxl))
|
||||
call split(vec,i)
|
||||
call forwardstep(vec,i)
|
||||
i=i/2
|
||||
enddo
|
||||
endif
|
||||
|
||||
if (tp == 3) then
|
||||
do while(i.ge.n/(2**mxl))
|
||||
call transformD8(vec,i)
|
||||
i=i/2
|
||||
enddo
|
||||
endif
|
||||
end subroutine
|
||||
|
||||
subroutine normalizationf(x,n)
|
||||
implicit none
|
||||
real x(*)
|
||||
integer n
|
||||
|
||||
integer k
|
||||
do k=1,n/2
|
||||
x(k)=x(k)*sqrt(2.0)
|
||||
enddo
|
||||
do k=n/2+1,n
|
||||
x(k)=x(k)*sqrt(2.0)/2
|
||||
enddo
|
||||
end
|
@ -1,31 +0,0 @@
|
||||
real function gaussian()
|
||||
implicit none
|
||||
! real rd
|
||||
|
||||
real x1,x2,w,y1
|
||||
real y2
|
||||
real n1,n2
|
||||
integer use_last
|
||||
integer ii,jj
|
||||
|
||||
use_last=0
|
||||
y2=0
|
||||
w=2.0
|
||||
if(use_last.ne.0) then
|
||||
y1=y2
|
||||
use_last=0
|
||||
else
|
||||
do while (w.ge.1.0)
|
||||
call random_number(n1)
|
||||
call random_number(n2)
|
||||
x1=2.0*n1-1.0
|
||||
x2=2.0*n2-1.0
|
||||
w = x1 * x1 + x2 * x2
|
||||
enddo
|
||||
w=((-2.0*log(w))/w)**0.5
|
||||
y1=x1*w
|
||||
y2=x2*w
|
||||
use_last=1
|
||||
endif
|
||||
gaussian=y1
|
||||
end function
|
@ -1,49 +0,0 @@
|
||||
subroutine predict(vec, N, direction )
|
||||
implicit none
|
||||
real vec(*)
|
||||
integer N !must be power of 2
|
||||
integer direction !0:forward 1:inverse
|
||||
!local variables
|
||||
integer half
|
||||
integer cnt,i,j
|
||||
real predictVal
|
||||
half = N/2
|
||||
cnt = 0
|
||||
|
||||
do i=1,half
|
||||
predictVal = vec(i)
|
||||
j = i + half
|
||||
if(direction == 0) then
|
||||
vec(j) = vec(j) - predictVal
|
||||
else if (direction == 1) then
|
||||
vec(j) = vec(j) + predictVal
|
||||
else
|
||||
print*,"haar::predict: bad direction value"
|
||||
stop
|
||||
endif
|
||||
enddo
|
||||
end subroutine
|
||||
|
||||
subroutine update( vec, N, direction )
|
||||
implicit none
|
||||
real vec(*)
|
||||
integer N !must be power of 2
|
||||
integer direction !0:forward 1:inverse
|
||||
!local variables
|
||||
integer half
|
||||
integer cnt,i,j
|
||||
real updateVal
|
||||
half = N/2
|
||||
do i=1,half
|
||||
j = i + half
|
||||
updateVal = vec(j) / 2.0
|
||||
if (direction == 0) then
|
||||
vec(i) = vec(i) + updateVal;
|
||||
else if (direction ==1) then
|
||||
vec(i) = vec(i) - updateVal
|
||||
else
|
||||
print*,"update: bad direction value"
|
||||
stop
|
||||
endif
|
||||
enddo
|
||||
end subroutine
|
@ -1,25 +0,0 @@
|
||||
subroutine inversestep(vec,n)
|
||||
implicit none
|
||||
integer n
|
||||
real vec(n)
|
||||
|
||||
integer half, k
|
||||
half=int(n/2.0)
|
||||
do k=1,half,1
|
||||
vec(k)=(sqrt(3.0)+1.0)/sqrt(2.0) * vec(k)
|
||||
vec(k+half)=(sqrt(3.0)-1.0)/sqrt(2.0) * vec(k+half)
|
||||
enddo
|
||||
do k=1,half-1,1
|
||||
vec(k)=vec(k)+vec(half+k+1)
|
||||
enddo
|
||||
vec(half)=vec(half)+vec(half+1)
|
||||
vec(half+1)=vec(half+1)+sqrt(3.0)/4.0*vec(1)+ &
|
||||
(sqrt(3.0)-2)/4.0*vec(half)
|
||||
do k=2,half,1
|
||||
vec(half+k)=vec(half+k)+sqrt(3.0)/4.0*vec(k)+ &
|
||||
(sqrt(3.0)-2)/4.0*vec(k-1)
|
||||
enddo
|
||||
do k=1,half,1
|
||||
vec(k)=vec(k)-sqrt(3.0)*vec(half+k)
|
||||
enddo
|
||||
end subroutine
|
@ -1,47 +0,0 @@
|
||||
subroutine inversetrans(vec,n,mxl,tp)
|
||||
implicit none
|
||||
integer n
|
||||
real vec(n)
|
||||
integer i
|
||||
integer mxl,tp
|
||||
integer inverse
|
||||
i=n/(2**mxl) !n-->n/2
|
||||
if (tp == 1) then
|
||||
inverse=1
|
||||
do while (i.le.n)
|
||||
call normalizationi(vec,i)
|
||||
call update(vec,i,inverse)
|
||||
call predict(vec,i,inverse)
|
||||
call merge1(vec,i)
|
||||
i=i*2
|
||||
enddo
|
||||
endif
|
||||
if (tp == 2) then
|
||||
do while (i.le.n)
|
||||
call inversestep(vec,i)
|
||||
call merge1(vec,i)
|
||||
i=i*2
|
||||
enddo
|
||||
endif
|
||||
if (tp == 3) then
|
||||
do while (i.le.n)
|
||||
call invTransformD8(vec,i)
|
||||
i=i*2
|
||||
enddo
|
||||
endif
|
||||
end subroutine
|
||||
|
||||
|
||||
subroutine normalizationi(x,i)
|
||||
implicit none
|
||||
real x(*)
|
||||
integer i
|
||||
|
||||
integer k
|
||||
do k=1,i/2
|
||||
x(k)=x(k)/sqrt(2.0)
|
||||
enddo
|
||||
do k=i/2+1,i
|
||||
x(k)=x(k)*sqrt(2.0)
|
||||
enddo
|
||||
end
|
@ -1,32 +0,0 @@
|
||||
subroutine invwavetrans(nx,ny,nz,x,mxl,mxld,HorizonType,VerticalType)
|
||||
implicit none
|
||||
integer mxl,mxld,HorizonType,VerticalType
|
||||
integer nx,ny,nz
|
||||
real x(*)
|
||||
real fxs(nx),fys(ny),fzs(nz)
|
||||
integer k,j,i
|
||||
!c local variables
|
||||
do k=1,ny
|
||||
do j=1,nx
|
||||
fzs=x(j+(k-1)*nx:j+(k-1)*nx+(nz-1)*nx*ny:nx*ny)
|
||||
call inversetrans(fzs,nz,mxld,VerticalType)
|
||||
x(j+(k-1)*nx:j+(k-1)*nx+(nz-1)*nx*ny:nx*ny)=fzs
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do k=1,nz
|
||||
do j=1,nx
|
||||
fys=x(j+(k-1)*nx*ny:j+(ny-1)*nx+(k-1)*nx*ny:nx)
|
||||
call inversetrans(fys,ny,mxl,HorizonType)
|
||||
x(j+(k-1)*nx*ny:j+(ny-1)*nx+(k-1)*nx*ny:nx)=fys
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do k=1,nz
|
||||
do j=1,ny
|
||||
fxs=x(1+(j-1)*nx+(k-1)*nx*ny:nx+(j-1)*nx+(k-1)*nx*ny)
|
||||
call inversetrans(fxs,nx,mxl,HorizonType)
|
||||
x(1+(j-1)*nx+(k-1)*nx*ny:nx+(j-1)*nx+(k-1)*nx*ny)=fxs
|
||||
enddo
|
||||
enddo
|
||||
end subroutine
|
@ -1,24 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrDataModule.f90
|
||||
!
|
||||
! Defines real(dp) and a few constants for use in other modules.
|
||||
!
|
||||
! 24 Oct 2007: Allows floating-point precision dp to be defined
|
||||
! in exactly one place (here). Note that we need
|
||||
! use lsmrDataModule
|
||||
! at the beginning of modules AND inside interfaces.
|
||||
! zero and one are not currently used by LSMR,
|
||||
! but this shows how they should be declared
|
||||
! by a user routine that does need them.
|
||||
! 16 Jul 2010: LSMR version derived from LSQR equivalent.
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
module lsmrDataModule
|
||||
|
||||
implicit none
|
||||
|
||||
intrinsic :: selected_real_kind
|
||||
integer, parameter, public :: dp = selected_real_kind(4)
|
||||
real(dp), parameter, public :: zero = 0.0_dp, one = 1.0_dp
|
||||
|
||||
end module lsmrDataModule
|
@ -1,754 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrModule.f90
|
||||
!
|
||||
! LSMR
|
||||
!
|
||||
! LSMR solves Ax = b or min ||Ax - b|| with or without damping,
|
||||
! using the iterative algorithm of David Fong and Michael Saunders:
|
||||
! http://www.stanford.edu/group/SOL/software/lsmr.html
|
||||
!
|
||||
! Maintained by
|
||||
! David Fong <clfong@stanford.edu>
|
||||
! Michael Saunders <saunders@stanford.edu>
|
||||
! Systems Optimization Laboratory (SOL)
|
||||
! Stanford University
|
||||
! Stanford, CA 94305-4026, USA
|
||||
!
|
||||
! 17 Jul 2010: F90 LSMR derived from F90 LSQR and lsqr.m.
|
||||
! 07 Sep 2010: Local reorthogonalization now works (localSize > 0).
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
module lsmrModule
|
||||
|
||||
use lsmrDataModule, only : dp
|
||||
use lsmrblasInterface, only : dnrm2, dscal
|
||||
implicit none
|
||||
private
|
||||
public :: LSMR
|
||||
|
||||
contains
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
! subroutine LSMR ( m, n, Aprod1, Aprod2, b, damp, &
|
||||
! atol, btol, conlim, itnlim, localSize, nout, &
|
||||
! x, istop, itn, normA, condA, normr, normAr, normx )
|
||||
subroutine LSMR ( m, n, leniw, lenrw,iw,rw, b, damp, &
|
||||
atol, btol, conlim, itnlim, localSize, nout, &
|
||||
x, istop, itn, normA, condA, normr, normAr, normx )
|
||||
|
||||
integer, intent(in) :: leniw
|
||||
integer, intent(in) :: lenrw
|
||||
integer, intent(in) :: iw(leniw)
|
||||
real, intent(in) :: rw(lenrw)
|
||||
|
||||
integer, intent(in) :: m, n, itnlim, localSize, nout
|
||||
integer, intent(out) :: istop, itn
|
||||
real(dp), intent(in) :: b(m)
|
||||
real(dp), intent(out) :: x(n)
|
||||
real(dp), intent(in) :: atol, btol, conlim, damp
|
||||
real(dp), intent(out) :: normA, condA, normr, normAr, normx
|
||||
|
||||
interface
|
||||
subroutine aprod(mode,m,n,x,y,leniw,lenrw,iw,rw) ! y := y + A*x
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: mode,lenrw
|
||||
integer, intent(in) :: leniw
|
||||
real, intent(in) :: rw(lenrw)
|
||||
integer, intent(in) :: iw(leniw)
|
||||
integer, intent(in) :: m,n
|
||||
real(dp), intent(inout) :: x(n)
|
||||
real(dp), intent(inout) :: y(m)
|
||||
end subroutine aprod
|
||||
! subroutine Aprod1(m,n,x,y) ! y := y + A*x
|
||||
! use lsmrDataModule, only : dp
|
||||
! integer, intent(in) :: m,n
|
||||
! real(dp), intent(in) :: x(n)
|
||||
! real(dp), intent(inout) :: y(m)
|
||||
! end subroutine Aprod1
|
||||
!
|
||||
! subroutine Aprod2(m,n,x,y) ! x := x + A'*y
|
||||
! use lsmrDataModule, only : dp
|
||||
! integer, intent(in) :: m,n
|
||||
! real(dp), intent(inout) :: x(n)
|
||||
! real(dp), intent(in) :: y(m)
|
||||
! end subroutine Aprod2
|
||||
end interface
|
||||
|
||||
!-------------------------------------------------------------------
|
||||
! LSMR finds a solution x to the following problems:
|
||||
!
|
||||
! 1. Unsymmetric equations: Solve A*x = b
|
||||
!
|
||||
! 2. Linear least squares: Solve A*x = b
|
||||
! in the least-squares sense
|
||||
!
|
||||
! 3. Damped least squares: Solve ( A )*x = ( b )
|
||||
! ( damp*I ) ( 0 )
|
||||
! in the least-squares sense
|
||||
!
|
||||
! where A is a matrix with m rows and n columns, b is an m-vector,
|
||||
! and damp is a scalar. (All quantities are real.)
|
||||
! The matrix A is treated as a linear operator. It is accessed
|
||||
! by means of subroutine calls with the following purpose:
|
||||
!
|
||||
! call Aprod1(m,n,x,y) must compute y = y + A*x without altering x.
|
||||
! call Aprod2(m,n,x,y) must compute x = x + A'*y without altering y.
|
||||
!
|
||||
! LSMR uses an iterative method to approximate the solution.
|
||||
! The number of iterations required to reach a certain accuracy
|
||||
! depends strongly on the scaling of the problem. Poor scaling of
|
||||
! the rows or columns of A should therefore be avoided where
|
||||
! possible.
|
||||
!
|
||||
! For example, in problem 1 the solution is unaltered by
|
||||
! row-scaling. If a row of A is very small or large compared to
|
||||
! the other rows of A, the corresponding row of ( A b ) should be
|
||||
! scaled up or down.
|
||||
!
|
||||
! In problems 1 and 2, the solution x is easily recovered
|
||||
! following column-scaling. Unless better information is known,
|
||||
! the nonzero columns of A should be scaled so that they all have
|
||||
! the same Euclidean norm (e.g., 1.0).
|
||||
!
|
||||
! In problem 3, there is no freedom to re-scale if damp is
|
||||
! nonzero. However, the value of damp should be assigned only
|
||||
! after attention has been paid to the scaling of A.
|
||||
!
|
||||
! The parameter damp is intended to help regularize
|
||||
! ill-conditioned systems, by preventing the true solution from
|
||||
! being very large. Another aid to regularization is provided by
|
||||
! the parameter condA, which may be used to terminate iterations
|
||||
! before the computed solution becomes very large.
|
||||
!
|
||||
! Note that x is not an input parameter.
|
||||
! If some initial estimate x0 is known and if damp = 0,
|
||||
! one could proceed as follows:
|
||||
!
|
||||
! 1. Compute a residual vector r0 = b - A*x0.
|
||||
! 2. Use LSMR to solve the system A*dx = r0.
|
||||
! 3. Add the correction dx to obtain a final solution x = x0 + dx.
|
||||
!
|
||||
! This requires that x0 be available before and after the call
|
||||
! to LSMR. To judge the benefits, suppose LSMR takes k1 iterations
|
||||
! to solve A*x = b and k2 iterations to solve A*dx = r0.
|
||||
! If x0 is "good", norm(r0) will be smaller than norm(b).
|
||||
! If the same stopping tolerances atol and btol are used for each
|
||||
! system, k1 and k2 will be similar, but the final solution x0 + dx
|
||||
! should be more accurate. The only way to reduce the total work
|
||||
! is to use a larger stopping tolerance for the second system.
|
||||
! If some value btol is suitable for A*x = b, the larger value
|
||||
! btol*norm(b)/norm(r0) should be suitable for A*dx = r0.
|
||||
!
|
||||
! Preconditioning is another way to reduce the number of iterations.
|
||||
! If it is possible to solve a related system M*x = b efficiently,
|
||||
! where M approximates A in some helpful way
|
||||
! (e.g. M - A has low rank or its elements are small relative to
|
||||
! those of A), LSMR may converge more rapidly on the system
|
||||
! A*M(inverse)*z = b,
|
||||
! after which x can be recovered by solving M*x = z.
|
||||
!
|
||||
! NOTE: If A is symmetric, LSMR should not be used!
|
||||
! Alternatives are the symmetric conjugate-gradient method (CG)
|
||||
! and/or SYMMLQ.
|
||||
! SYMMLQ is an implementation of symmetric CG that applies to
|
||||
! any symmetric A and will converge more rapidly than LSMR.
|
||||
! If A is positive definite, there are other implementations of
|
||||
! symmetric CG that require slightly less work per iteration
|
||||
! than SYMMLQ (but will take the same number of iterations).
|
||||
!
|
||||
!
|
||||
! Notation
|
||||
! --------
|
||||
! The following quantities are used in discussing the subroutine
|
||||
! parameters:
|
||||
!
|
||||
! Abar = ( A ), bbar = (b)
|
||||
! (damp*I) (0)
|
||||
!
|
||||
! r = b - A*x, rbar = bbar - Abar*x
|
||||
!
|
||||
! normr = sqrt( norm(r)**2 + damp**2 * norm(x)**2 )
|
||||
! = norm( rbar )
|
||||
!
|
||||
! eps = the relative precision of floating-point arithmetic.
|
||||
! On most machines, eps is about 1.0e-7 and 1.0e-16
|
||||
! in single and double precision respectively.
|
||||
! We expect eps to be about 1e-16 always.
|
||||
!
|
||||
! LSMR minimizes the function normr with respect to x.
|
||||
!
|
||||
!
|
||||
! Parameters
|
||||
! ----------
|
||||
! m input m, the number of rows in A.
|
||||
!
|
||||
! n input n, the number of columns in A.
|
||||
!
|
||||
! Aprod1, Aprod2 See above.
|
||||
!
|
||||
! damp input The damping parameter for problem 3 above.
|
||||
! (damp should be 0.0 for problems 1 and 2.)
|
||||
! If the system A*x = b is incompatible, values
|
||||
! of damp in the range 0 to sqrt(eps)*norm(A)
|
||||
! will probably have a negligible effect.
|
||||
! Larger values of damp will tend to decrease
|
||||
! the norm of x and reduce the number of
|
||||
! iterations required by LSMR.
|
||||
!
|
||||
! The work per iteration and the storage needed
|
||||
! by LSMR are the same for all values of damp.
|
||||
!
|
||||
! b(m) input The rhs vector b.
|
||||
!
|
||||
! x(n) output Returns the computed solution x.
|
||||
!
|
||||
! atol input An estimate of the relative error in the data
|
||||
! defining the matrix A. For example, if A is
|
||||
! accurate to about 6 digits, set atol = 1.0e-6.
|
||||
!
|
||||
! btol input An estimate of the relative error in the data
|
||||
! defining the rhs b. For example, if b is
|
||||
! accurate to about 6 digits, set btol = 1.0e-6.
|
||||
!
|
||||
! conlim input An upper limit on cond(Abar), the apparent
|
||||
! condition number of the matrix Abar.
|
||||
! Iterations will be terminated if a computed
|
||||
! estimate of cond(Abar) exceeds conlim.
|
||||
! This is intended to prevent certain small or
|
||||
! zero singular values of A or Abar from
|
||||
! coming into effect and causing unwanted growth
|
||||
! in the computed solution.
|
||||
!
|
||||
! conlim and damp may be used separately or
|
||||
! together to regularize ill-conditioned systems.
|
||||
!
|
||||
! Normally, conlim should be in the range
|
||||
! 1000 to 1/eps.
|
||||
! Suggested value:
|
||||
! conlim = 1/(100*eps) for compatible systems,
|
||||
! conlim = 1/(10*sqrt(eps)) for least squares.
|
||||
!
|
||||
! Note: Any or all of atol, btol, conlim may be set to zero.
|
||||
! The effect will be the same as the values eps, eps, 1/eps.
|
||||
!
|
||||
! itnlim input An upper limit on the number of iterations.
|
||||
! Suggested value:
|
||||
! itnlim = n/2 for well-conditioned systems
|
||||
! with clustered singular values,
|
||||
! itnlim = 4*n otherwise.
|
||||
!
|
||||
! localSize input No. of vectors for local reorthogonalization.
|
||||
! 0 No reorthogonalization is performed.
|
||||
! >0 This many n-vectors "v" (the most recent ones)
|
||||
! are saved for reorthogonalizing the next v.
|
||||
! localSize need not be more than min(m,n).
|
||||
! At most min(m,n) vectors will be allocated.
|
||||
!
|
||||
! nout input File number for printed output. If positive,
|
||||
! a summary will be printed on file nout.
|
||||
!
|
||||
! istop output An integer giving the reason for termination:
|
||||
!
|
||||
! 0 x = 0 is the exact solution.
|
||||
! No iterations were performed.
|
||||
!
|
||||
! 1 The equations A*x = b are probably compatible.
|
||||
! Norm(A*x - b) is sufficiently small, given the
|
||||
! values of atol and btol.
|
||||
!
|
||||
! 2 damp is zero. The system A*x = b is probably
|
||||
! not compatible. A least-squares solution has
|
||||
! been obtained that is sufficiently accurate,
|
||||
! given the value of atol.
|
||||
!
|
||||
! 3 damp is nonzero. A damped least-squares
|
||||
! solution has been obtained that is sufficiently
|
||||
! accurate, given the value of atol.
|
||||
!
|
||||
! 4 An estimate of cond(Abar) has exceeded conlim.
|
||||
! The system A*x = b appears to be ill-conditioned,
|
||||
! or there could be an error in Aprod1 or Aprod2.
|
||||
!
|
||||
! 5 The iteration limit itnlim was reached.
|
||||
!
|
||||
! itn output The number of iterations performed.
|
||||
!
|
||||
! normA output An estimate of the Frobenius norm of Abar.
|
||||
! This is the square-root of the sum of squares
|
||||
! of the elements of Abar.
|
||||
! If damp is small and the columns of A
|
||||
! have all been scaled to have length 1.0,
|
||||
! normA should increase to roughly sqrt(n).
|
||||
! A radically different value for normA may
|
||||
! indicate an error in Aprod1 or Aprod2.
|
||||
!
|
||||
! condA output An estimate of cond(Abar), the condition
|
||||
! number of Abar. A very high value of condA
|
||||
! may again indicate an error in Aprod1 or Aprod2.
|
||||
!
|
||||
! normr output An estimate of the final value of norm(rbar),
|
||||
! the function being minimized (see notation
|
||||
! above). This will be small if A*x = b has
|
||||
! a solution.
|
||||
!
|
||||
! normAr output An estimate of the final value of
|
||||
! norm( Abar'*rbar ), the norm of
|
||||
! the residual for the normal equations.
|
||||
! This should be small in all cases. (normAr
|
||||
! will often be smaller than the true value
|
||||
! computed from the output vector x.)
|
||||
!
|
||||
! normx output An estimate of norm(x) for the final solution x.
|
||||
!
|
||||
! Subroutines and functions used
|
||||
! ------------------------------
|
||||
! BLAS dscal, dnrm2
|
||||
! USER Aprod1, Aprod2
|
||||
!
|
||||
! Precision
|
||||
! ---------
|
||||
! The number of iterations required by LSMR will decrease
|
||||
! if the computation is performed in higher precision.
|
||||
! At least 15-digit arithmetic should normally be used.
|
||||
! "real(dp)" declarations should normally be 8-byte words.
|
||||
! If this ever changes, the BLAS routines dnrm2, dscal
|
||||
! (Lawson, et al., 1979) will also need to be changed.
|
||||
!
|
||||
!
|
||||
! Reference
|
||||
! ---------
|
||||
! http://www.stanford.edu/group/SOL/software/lsmr.html
|
||||
! ------------------------------------------------------------------
|
||||
!
|
||||
! LSMR development:
|
||||
! 21 Sep 2007: Fortran 90 version of LSQR implemented.
|
||||
! Aprod1, Aprod2 implemented via f90 interface.
|
||||
! 17 Jul 2010: LSMR derived from LSQR and lsmr.m.
|
||||
! 07 Sep 2010: Local reorthogonalization now working.
|
||||
!-------------------------------------------------------------------
|
||||
|
||||
intrinsic :: abs, dot_product, min, max, sqrt
|
||||
|
||||
! Local arrays and variables
|
||||
real(dp) :: h(n), hbar(n), u(m), v(n), w(n), localV(n,min(localSize,m,n))
|
||||
logical :: damped, localOrtho, localVQueueFull, prnt, show
|
||||
integer :: i, localOrthoCount, localOrthoLimit, localPointer, localVecs, &
|
||||
pcount, pfreq
|
||||
real(dp) :: alpha, alphabar, alphahat, &
|
||||
beta, betaacute, betacheck, betad, betadd, betahat, &
|
||||
normb, c, cbar, chat, ctildeold, ctol, &
|
||||
d, maxrbar, minrbar, normA2, &
|
||||
rho, rhobar, rhobarold, rhodold, rhoold, rhotemp, &
|
||||
rhotildeold, rtol, s, sbar, shat, stildeold, &
|
||||
t1, taud, tautildeold, test1, test2, test3, &
|
||||
thetabar, thetanew, thetatilde, thetatildeold, &
|
||||
zeta, zetabar, zetaold
|
||||
|
||||
! Local constants
|
||||
real(dp), parameter :: zero = 0.0_dp, one = 1.0_dp
|
||||
character(len=*), parameter :: enter = ' Enter LSMR. '
|
||||
character(len=*), parameter :: exitt = ' Exit LSMR. '
|
||||
character(len=*), parameter :: msg(0:7) = &
|
||||
(/ 'The exact solution is x = 0 ', &
|
||||
'Ax - b is small enough, given atol, btol ', &
|
||||
'The least-squares solution is good enough, given atol', &
|
||||
'The estimate of cond(Abar) has exceeded conlim ', &
|
||||
'Ax - b is small enough for this machine ', &
|
||||
'The LS solution is good enough for this machine ', &
|
||||
'Cond(Abar) seems to be too large for this machine ', &
|
||||
'The iteration limit has been reached ' /)
|
||||
!-------------------------------------------------------------------
|
||||
|
||||
|
||||
! Initialize.
|
||||
|
||||
localVecs = min(localSize,m,n)
|
||||
show = nout > 0
|
||||
if (show) then
|
||||
write(nout, 1000) enter,m,n,damp,atol,conlim,btol,itnlim,localVecs
|
||||
end if
|
||||
|
||||
pfreq = 20 ! print frequency (for repeating the heading)
|
||||
pcount = 0 ! print counter
|
||||
damped = damp > zero !
|
||||
|
||||
!-------------------------------------------------------------------
|
||||
! Set up the first vectors u and v for the bidiagonalization.
|
||||
! These satisfy beta*u = b, alpha*v = A(transpose)*u.
|
||||
!-------------------------------------------------------------------
|
||||
u(1:m) = b(1:m)
|
||||
v(1:n) = zero
|
||||
x(1:n) = zero
|
||||
|
||||
alpha = zero
|
||||
beta = dnrm2 (m, u, 1)
|
||||
|
||||
if (beta > zero) then
|
||||
call dscal (m, (one/beta), u, 1)
|
||||
! call Aprod2(m, n, v, u) ! v = A'*u
|
||||
call aprod(2,m,n,v,u,leniw,lenrw,iw,rw)
|
||||
alpha = dnrm2 (n, v, 1)
|
||||
end if
|
||||
|
||||
if (alpha > zero) then
|
||||
call dscal (n, (one/alpha), v, 1)
|
||||
w = v
|
||||
end if
|
||||
|
||||
normAr = alpha*beta
|
||||
if (normAr == zero) go to 800
|
||||
|
||||
! Initialization for local reorthogonalization.
|
||||
|
||||
localOrtho = .false.
|
||||
if (localVecs > 0) then
|
||||
localPointer = 1
|
||||
localOrtho = .true.
|
||||
localVQueueFull = .false.
|
||||
localV(:,1) = v
|
||||
end if
|
||||
|
||||
! Initialize variables for 1st iteration.
|
||||
|
||||
itn = 0
|
||||
zetabar = alpha*beta
|
||||
alphabar = alpha
|
||||
rho = 1
|
||||
rhobar = 1
|
||||
cbar = 1
|
||||
sbar = 0
|
||||
|
||||
h = v
|
||||
hbar(1:n) = zero
|
||||
x(1:n) = zero
|
||||
|
||||
! Initialize variables for estimation of ||r||.
|
||||
|
||||
betadd = beta
|
||||
betad = 0
|
||||
rhodold = 1
|
||||
tautildeold = 0
|
||||
thetatilde = 0
|
||||
zeta = 0
|
||||
d = 0
|
||||
|
||||
! Initialize variables for estimation of ||A|| and cond(A).
|
||||
|
||||
normA2 = alpha**2
|
||||
maxrbar = 0_dp
|
||||
minrbar = 1e+30_dp
|
||||
|
||||
! Items for use in stopping rules.
|
||||
normb = beta
|
||||
istop = 0
|
||||
ctol = zero
|
||||
if (conlim > zero) ctol = one/conlim
|
||||
normr = beta
|
||||
|
||||
! Exit if b=0 or A'b = 0.
|
||||
|
||||
normAr = alpha * beta
|
||||
if (normAr == 0) then
|
||||
if (show) then
|
||||
write(nout,'(a)') msg(1)
|
||||
end if
|
||||
return
|
||||
end if
|
||||
|
||||
! Heading for iteration log.
|
||||
|
||||
if (show) then
|
||||
if (damped) then
|
||||
write(nout,1300)
|
||||
else
|
||||
write(nout,1200)
|
||||
end if
|
||||
test1 = one
|
||||
test2 = alpha/beta
|
||||
write(nout, 1500) itn,x(1),normr,normAr,test1,test2
|
||||
end if
|
||||
|
||||
!===================================================================
|
||||
! Main iteration loop.
|
||||
!===================================================================
|
||||
do
|
||||
itn = itn + 1
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! Perform the next step of the bidiagonalization to obtain the
|
||||
! next beta, u, alpha, v. These satisfy
|
||||
! beta*u = A*v - alpha*u,
|
||||
! alpha*v = A'*u - beta*v.
|
||||
!----------------------------------------------------------------
|
||||
call dscal (m,(- alpha), u, 1)
|
||||
! call Aprod1(m, n, v, u) ! u = A*v
|
||||
call aprod ( 1,m,n,v,u,leniw,lenrw,iw,rw )
|
||||
beta = dnrm2 (m, u, 1)
|
||||
|
||||
if (beta > zero) then
|
||||
call dscal (m, (one/beta), u, 1)
|
||||
if (localOrtho) then ! Store v into the circular buffer localV.
|
||||
call localVEnqueue ! Store old v for local reorthog'n of new v.
|
||||
end if
|
||||
call dscal (n, (- beta), v, 1)
|
||||
|
||||
!call Aprod2(m, n, v, u) ! v = A'*u
|
||||
call aprod ( 2,m,n,v,u,leniw,lenrw,iw,rw )
|
||||
if (localOrtho) then ! Perform local reorthogonalization of V.
|
||||
call localVOrtho ! Local-reorthogonalization of new v.
|
||||
end if
|
||||
alpha = dnrm2 (n, v, 1)
|
||||
if (alpha > zero) then
|
||||
call dscal (n, (one/alpha), v, 1)
|
||||
end if
|
||||
end if
|
||||
|
||||
! At this point, beta = beta_{k+1}, alpha = alpha_{k+1}.
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! Construct rotation Qhat_{k,2k+1}.
|
||||
|
||||
alphahat = d2norm(alphabar, damp)
|
||||
chat = alphabar/alphahat
|
||||
shat = damp/alphahat
|
||||
|
||||
! Use a plane rotation (Q_i) to turn B_i to R_i.
|
||||
|
||||
rhoold = rho
|
||||
rho = d2norm(alphahat, beta)
|
||||
c = alphahat/rho
|
||||
s = beta/rho
|
||||
thetanew = s*alpha
|
||||
alphabar = c*alpha
|
||||
|
||||
! Use a plane rotation (Qbar_i) to turn R_i^T into R_i^bar.
|
||||
|
||||
rhobarold = rhobar
|
||||
zetaold = zeta
|
||||
thetabar = sbar*rho
|
||||
rhotemp = cbar*rho
|
||||
rhobar = d2norm(cbar*rho, thetanew)
|
||||
cbar = cbar*rho/rhobar
|
||||
sbar = thetanew/rhobar
|
||||
zeta = cbar*zetabar
|
||||
zetabar = - sbar*zetabar
|
||||
|
||||
! Update h, h_hat, x.
|
||||
|
||||
hbar = h - (thetabar*rho/(rhoold*rhobarold))*hbar
|
||||
x = x + (zeta/(rho*rhobar))*hbar
|
||||
h = v - (thetanew/rho)*h
|
||||
|
||||
! Estimate ||r||.
|
||||
|
||||
! Apply rotation Qhat_{k,2k+1}.
|
||||
betaacute = chat* betadd
|
||||
betacheck = - shat* betadd
|
||||
|
||||
! Apply rotation Q_{k,k+1}.
|
||||
betahat = c*betaacute
|
||||
betadd = - s*betaacute
|
||||
|
||||
! Apply rotation Qtilde_{k-1}.
|
||||
! betad = betad_{k-1} here.
|
||||
|
||||
thetatildeold = thetatilde
|
||||
rhotildeold = d2norm(rhodold, thetabar)
|
||||
ctildeold = rhodold/rhotildeold
|
||||
stildeold = thetabar/rhotildeold
|
||||
thetatilde = stildeold* rhobar
|
||||
rhodold = ctildeold* rhobar
|
||||
betad = - stildeold*betad + ctildeold*betahat
|
||||
|
||||
! betad = betad_k here.
|
||||
! rhodold = rhod_k here.
|
||||
|
||||
tautildeold = (zetaold - thetatildeold*tautildeold)/rhotildeold
|
||||
taud = (zeta - thetatilde*tautildeold)/rhodold
|
||||
d = d + betacheck**2
|
||||
normr = sqrt(d + (betad - taud)**2 + betadd**2)
|
||||
|
||||
! Estimate ||A||.
|
||||
normA2 = normA2 + beta**2
|
||||
normA = sqrt(normA2)
|
||||
normA2 = normA2 + alpha**2
|
||||
|
||||
! Estimate cond(A).
|
||||
maxrbar = max(maxrbar,rhobarold)
|
||||
if (itn > 1) then
|
||||
minrbar = min(minrbar,rhobarold)
|
||||
end if
|
||||
condA = max(maxrbar,rhotemp)/min(minrbar,rhotemp)
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! Test for convergence.
|
||||
!----------------------------------------------------------------
|
||||
|
||||
! Compute norms for convergence testing.
|
||||
normAr = abs(zetabar)
|
||||
normx = dnrm2(n, x, 1)
|
||||
|
||||
! Now use these norms to estimate certain other quantities,
|
||||
! some of which will be small near a solution.
|
||||
|
||||
test1 = normr /normb
|
||||
test2 = normAr/(normA*normr)
|
||||
test3 = one/condA
|
||||
t1 = test1/(one + normA*normx/normb)
|
||||
rtol = btol + atol*normA*normx/normb
|
||||
|
||||
! The following tests guard against extremely small values of
|
||||
! atol, btol or ctol. (The user may have set any or all of
|
||||
! the parameters atol, btol, conlim to 0.)
|
||||
! The effect is equivalent to the normAl tests using
|
||||
! atol = eps, btol = eps, conlim = 1/eps.
|
||||
|
||||
if (itn >= itnlim) istop = 7
|
||||
if (one+test3 <= one) istop = 6
|
||||
if (one+test2 <= one) istop = 5
|
||||
if (one+t1 <= one) istop = 4
|
||||
|
||||
! Allow for tolerances set by the user.
|
||||
|
||||
if ( test3 <= ctol) istop = 3
|
||||
if ( test2 <= atol) istop = 2
|
||||
if ( test1 <= rtol) istop = 1
|
||||
|
||||
!----------------------------------------------------------------
|
||||
! See if it is time to print something.
|
||||
!----------------------------------------------------------------
|
||||
prnt = .false.
|
||||
if (show) then
|
||||
if (n <= 40) prnt = .true.
|
||||
if (itn <= 10) prnt = .true.
|
||||
if (itn >= itnlim-10) prnt = .true.
|
||||
if (mod(itn,10) == 0) prnt = .true.
|
||||
if (test3 <= 1.1*ctol) prnt = .true.
|
||||
if (test2 <= 1.1*atol) prnt = .true.
|
||||
if (test1 <= 1.1*rtol) prnt = .true.
|
||||
if (istop /= 0) prnt = .true.
|
||||
|
||||
if (prnt) then ! Print a line for this iteration
|
||||
if (pcount >= pfreq) then ! Print a heading first
|
||||
pcount = 0
|
||||
if (damped) then
|
||||
write(nout,1300)
|
||||
else
|
||||
write(nout,1200)
|
||||
end if
|
||||
end if
|
||||
pcount = pcount + 1
|
||||
write(nout,1500) itn,x(1),normr,normAr,test1,test2,normA,condA
|
||||
end if
|
||||
end if
|
||||
|
||||
if (istop /= 0) exit
|
||||
end do
|
||||
!===================================================================
|
||||
! End of iteration loop.
|
||||
!===================================================================
|
||||
|
||||
! Come here if normAr = 0, or if normal exit.
|
||||
|
||||
800 if (damped .and. istop==2) istop=3 ! Decide if istop = 2 or 3.
|
||||
if (show) then ! Print the stopping condition.
|
||||
write(nout, 2000) &
|
||||
exitt,istop,itn, &
|
||||
exitt,normA,condA, &
|
||||
exitt,normb, normx, &
|
||||
exitt,normr,normAr
|
||||
write(nout, 3000) &
|
||||
exitt, msg(istop)
|
||||
end if
|
||||
|
||||
return
|
||||
|
||||
1000 format(// a, ' Least-squares solution of Ax = b' &
|
||||
/ ' The matrix A has', i7, ' rows and', i7, ' columns' &
|
||||
/ ' damp =', es22.14 &
|
||||
/ ' atol =', es10.2, 15x, 'conlim =', es10.2 &
|
||||
/ ' btol =', es10.2, 15x, 'itnlim =', i10 &
|
||||
/ ' localSize (no. of vectors for local reorthogonalization) =', i7)
|
||||
1200 format(/ " Itn x(1) norm r A'r ", &
|
||||
' Compatible LS norm A cond A')
|
||||
1300 format(/ " Itn x(1) norm rbar Abar'rbar", &
|
||||
' Compatible LS norm Abar cond Abar')
|
||||
1500 format(i6, 2es17.9, 5es10.2)
|
||||
2000 format(/ a, 5x, 'istop =', i2, 15x, 'itn =', i8 &
|
||||
/ a, 5x, 'normA =', es12.5, 5x, 'condA =', es12.5 &
|
||||
/ a, 5x, 'normb =', es12.5, 5x, 'normx =', es12.5 &
|
||||
/ a, 5x, 'normr =', es12.5, 5x, 'normAr =', es12.5)
|
||||
3000 format(a, 5x, a)
|
||||
|
||||
contains
|
||||
|
||||
function d2norm( a, b )
|
||||
|
||||
real(dp) :: d2norm
|
||||
real(dp), intent(in) :: a, b
|
||||
|
||||
!-------------------------------------------------------------------
|
||||
! d2norm returns sqrt( a**2 + b**2 )
|
||||
! with precautions to avoid overflow.
|
||||
!
|
||||
! 21 Mar 1990: First version.
|
||||
! 17 Sep 2007: Fortran 90 version.
|
||||
! 24 Oct 2007: User real(dp) instead of compiler option -r8.
|
||||
!-------------------------------------------------------------------
|
||||
|
||||
intrinsic :: abs, sqrt
|
||||
real(dp) :: scale
|
||||
real(dp), parameter :: zero = 0.0_dp
|
||||
|
||||
scale = abs(a) + abs(b)
|
||||
if (scale == zero) then
|
||||
d2norm = zero
|
||||
else
|
||||
d2norm = scale*sqrt((a/scale)**2 + (b/scale)**2)
|
||||
end if
|
||||
|
||||
end function d2norm
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
subroutine localVEnqueue
|
||||
|
||||
! Store v into the circular buffer localV.
|
||||
|
||||
if (localPointer < localVecs) then
|
||||
localPointer = localPointer + 1
|
||||
else
|
||||
localPointer = 1
|
||||
localVQueueFull = .true.
|
||||
end if
|
||||
localV(:,localPointer) = v
|
||||
|
||||
end subroutine localVEnqueue
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
subroutine localVOrtho
|
||||
|
||||
! Perform local reorthogonalization of current v.
|
||||
|
||||
real(dp) :: d
|
||||
|
||||
if (localVQueueFull) then
|
||||
localOrthoLimit = localVecs
|
||||
else
|
||||
localOrthoLimit = localPointer
|
||||
end if
|
||||
|
||||
do localOrthoCount = 1, localOrthoLimit
|
||||
d = dot_product(v,localV(:,localOrthoCount))
|
||||
v = v - d * localV(:,localOrthoCount)
|
||||
end do
|
||||
|
||||
end subroutine localVOrtho
|
||||
|
||||
end subroutine LSMR
|
||||
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
end module LSMRmodule
|
@ -1,360 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrblas.f90 (double precision)
|
||||
!
|
||||
! This file contains the following BLAS routines
|
||||
! dcopy, ddot, dnrm2, dscal
|
||||
! required by subroutines LSMR and Acheck.
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
!
|
||||
!! DCOPY copies a vector X to a vector Y.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
! The routine uses unrolled loops for increments equal to one.
|
||||
!
|
||||
! Modified:
|
||||
! 16 May 2005
|
||||
!
|
||||
! Author:
|
||||
! Jack Dongarra
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
!
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of elements in DX and DY.
|
||||
!
|
||||
! Input, real ( kind = 8 ) DX(*), the first vector.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries of DX.
|
||||
!
|
||||
! Output, real ( kind = 8 ) DY(*), the second vector.
|
||||
!
|
||||
! Input, integer INCY, the increment between successive entries of DY.
|
||||
|
||||
|
||||
subroutine dcopy(n,dx,incx,dy,incy)
|
||||
|
||||
implicit none
|
||||
! double precision dx(*),dy(*)
|
||||
real(4) dx(*),dy(*)
|
||||
integer i,incx,incy,ix,iy,m,n
|
||||
|
||||
if ( n <= 0 ) then
|
||||
return
|
||||
end if
|
||||
|
||||
if ( incx == 1 .and. incy == 1 ) then
|
||||
|
||||
m = mod ( n, 7 )
|
||||
|
||||
if ( m /= 0 ) then
|
||||
dy(1:m) = dx(1:m)
|
||||
end if
|
||||
|
||||
do i = m+1, n, 7
|
||||
dy(i) = dx(i)
|
||||
dy(i + 1) = dx(i + 1)
|
||||
dy(i + 2) = dx(i + 2)
|
||||
dy(i + 3) = dx(i + 3)
|
||||
dy(i + 4) = dx(i + 4)
|
||||
dy(i + 5) = dx(i + 5)
|
||||
dy(i + 6) = dx(i + 6)
|
||||
end do
|
||||
|
||||
else
|
||||
|
||||
if ( 0 <= incx ) then
|
||||
ix = 1
|
||||
else
|
||||
ix = ( -n + 1 ) * incx + 1
|
||||
end if
|
||||
|
||||
if ( 0 <= incy ) then
|
||||
iy = 1
|
||||
else
|
||||
iy = ( -n + 1 ) * incy + 1
|
||||
end if
|
||||
|
||||
do i = 1, n
|
||||
dy(iy) = dx(ix)
|
||||
ix = ix + incx
|
||||
iy = iy + incy
|
||||
end do
|
||||
end if
|
||||
return
|
||||
end subroutine dcopy
|
||||
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!
|
||||
!! DDOT forms the dot product of two vectors.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
! This routine uses unrolled loops for increments equal to one.
|
||||
!
|
||||
! Modified:
|
||||
! 16 May 2005
|
||||
!
|
||||
! Author:
|
||||
! Jack Dongarra
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of entries in the vectors.
|
||||
!
|
||||
! Input, real ( kind = 8 ) DX(*), the first vector.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries in DX.
|
||||
!
|
||||
! Input, real ( kind = 8 ) DY(*), the second vector.
|
||||
!
|
||||
! Input, integer INCY, the increment between successive entries in DY.
|
||||
!
|
||||
! Output, real ( kind = 8 ) DDOT, the sum of the product of the
|
||||
! corresponding entries of DX and DY.
|
||||
|
||||
|
||||
! double precision function ddot(n,dx,incx,dy,incy)
|
||||
real(4) function ddot(n,dx,incx,dy,incy)
|
||||
|
||||
implicit none
|
||||
! double precision dx(*),dy(*),dtemp
|
||||
real(4) dx(*),dy(*),dtemp
|
||||
integer i,incx,incy,ix,iy,m,n
|
||||
|
||||
ddot = 0.0d0
|
||||
dtemp = 0.0d0
|
||||
if ( n <= 0 ) then
|
||||
return
|
||||
end if
|
||||
|
||||
! Code for unequal increments or equal increments
|
||||
! not equal to 1.
|
||||
|
||||
if ( incx /= 1 .or. incy /= 1 ) then
|
||||
|
||||
if ( 0 <= incx ) then
|
||||
ix = 1
|
||||
else
|
||||
ix = ( - n + 1 ) * incx + 1
|
||||
end if
|
||||
|
||||
if ( 0 <= incy ) then
|
||||
iy = 1
|
||||
else
|
||||
iy = ( - n + 1 ) * incy + 1
|
||||
end if
|
||||
|
||||
do i = 1, n
|
||||
dtemp = dtemp + dx(ix) * dy(iy)
|
||||
ix = ix + incx
|
||||
iy = iy + incy
|
||||
end do
|
||||
|
||||
! Code for both increments equal to 1.
|
||||
|
||||
else
|
||||
|
||||
m = mod ( n, 5 )
|
||||
|
||||
do i = 1, m
|
||||
dtemp = dtemp + dx(i) * dy(i)
|
||||
end do
|
||||
|
||||
do i = m+1, n, 5
|
||||
dtemp = dtemp + dx(i)*dy(i) + dx(i+1)*dy(i+1) + dx(i+2)*dy(i+2) &
|
||||
+ dx(i+3)*dy(i+3) + dx(i+4)*dy(i+4)
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
ddot = dtemp
|
||||
return
|
||||
end function ddot
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!*****************************************************************************80
|
||||
!
|
||||
!! DNRM2 returns the euclidean norm of a vector.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
! DNRM2 ( X ) = sqrt ( X' * X )
|
||||
!
|
||||
! Modified:
|
||||
! 16 May 2005
|
||||
!
|
||||
! Author:
|
||||
! Sven Hammarling
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of entries in the vector.
|
||||
!
|
||||
! Input, real ( kind = 8 ) X(*), the vector whose norm is to be computed.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries of X.
|
||||
!
|
||||
! Output, real ( kind = 8 ) DNRM2, the Euclidean norm of X.
|
||||
!
|
||||
|
||||
! double precision function dnrm2 ( n, x, incx)
|
||||
real(4) function dnrm2 ( n, x, incx)
|
||||
implicit none
|
||||
integer ix,n,incx
|
||||
! double precision x(*), ssq,absxi,norm,scale
|
||||
real(4) x(*), ssq,absxi,norm,scale
|
||||
|
||||
if ( n < 1 .or. incx < 1 ) then
|
||||
norm = 0.d0
|
||||
else if ( n == 1 ) then
|
||||
norm = abs ( x(1) )
|
||||
else
|
||||
scale = 0.d0
|
||||
ssq = 1.d0
|
||||
|
||||
do ix = 1, 1 + ( n - 1 )*incx, incx
|
||||
if ( x(ix) /= 0.d0 ) then
|
||||
absxi = abs ( x(ix) )
|
||||
if ( scale < absxi ) then
|
||||
ssq = 1.d0 + ssq * ( scale / absxi )**2
|
||||
scale = absxi
|
||||
else
|
||||
ssq = ssq + ( absxi / scale )**2
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
norm = scale * sqrt ( ssq )
|
||||
end if
|
||||
|
||||
dnrm2 = norm
|
||||
return
|
||||
end function dnrm2
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! DSCAL scales a vector by a constant.
|
||||
!
|
||||
! Discussion:
|
||||
! This routine uses double precision real arithmetic.
|
||||
!
|
||||
! Modified:
|
||||
! 08 April 1999
|
||||
!
|
||||
! Author:
|
||||
! Jack Dongarra
|
||||
! Fortran90 translation by John Burkardt.
|
||||
!
|
||||
! Reference:
|
||||
! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
|
||||
! LINPACK User's Guide,
|
||||
! SIAM, 1979,
|
||||
! ISBN13: 978-0-898711-72-1,
|
||||
! LC: QA214.L56.
|
||||
!
|
||||
! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
|
||||
! Algorithm 539,
|
||||
! Basic Linear Algebra Subprograms for Fortran Usage,
|
||||
! ACM Transactions on Mathematical Software,
|
||||
! Volume 5, Number 3, September 1979, pages 308-323.
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! Input, integer N, the number of entries in the vector.
|
||||
!
|
||||
! Input, real ( kind = 8 ) SA, the multiplier.
|
||||
!
|
||||
! Input/output, real ( kind = 8 ) X(*), the vector to be scaled.
|
||||
!
|
||||
! Input, integer INCX, the increment between successive entries of X.
|
||||
!
|
||||
|
||||
subroutine dscal(n,sa,x,incx)
|
||||
|
||||
implicit none
|
||||
|
||||
integer i
|
||||
integer incx
|
||||
integer ix
|
||||
integer m
|
||||
integer n
|
||||
!double precision sa
|
||||
!double precision x(*)
|
||||
|
||||
real(4) sa
|
||||
real(4) x(*)
|
||||
if ( n <= 0 ) then
|
||||
return
|
||||
else if ( incx == 1 ) then
|
||||
m = mod ( n, 5 )
|
||||
x(1:m) = sa * x(1:m)
|
||||
|
||||
do i = m+1, n, 5
|
||||
x(i) = sa * x(i)
|
||||
x(i+1) = sa * x(i+1)
|
||||
x(i+2) = sa * x(i+2)
|
||||
x(i+3) = sa * x(i+3)
|
||||
x(i+4) = sa * x(i+4)
|
||||
end do
|
||||
else
|
||||
if ( 0 <= incx ) then
|
||||
ix = 1
|
||||
else
|
||||
ix = ( - n + 1 ) * incx + 1
|
||||
end if
|
||||
|
||||
do i = 1, n
|
||||
x(ix) = sa * x(ix)
|
||||
ix = ix + incx
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
return
|
||||
end subroutine dscal
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
@ -1,41 +0,0 @@
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
! File lsmrblasInterface.f90
|
||||
!
|
||||
! BLAS1 Interfaces: ddot dnrm2 dscal
|
||||
!
|
||||
! Maintained by Michael Saunders <saunders@stanford.edu>.
|
||||
!
|
||||
! 19 Dec 2008: lsqrblasInterface module implemented.
|
||||
! Metcalf and Reid recommend putting interfaces in a module.
|
||||
! 16 Jul 2010: LSMR version derived from LSQR equivalent.
|
||||
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
module lsmrblasInterface
|
||||
|
||||
implicit none
|
||||
public :: ddot, dnrm2, dscal
|
||||
|
||||
interface ! Level 1 BLAS
|
||||
function ddot (n,dx,incx,dy,incy)
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: n,incx,incy
|
||||
real(dp), intent(in) :: dx(*),dy(*)
|
||||
real(dp) :: ddot
|
||||
end function ddot
|
||||
|
||||
function dnrm2 (n,dx,incx)
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: n,incx
|
||||
real(dp), intent(in) :: dx(*)
|
||||
real(dp) :: dnrm2
|
||||
end function dnrm2
|
||||
|
||||
subroutine dscal (n,sa,x,incx)
|
||||
use lsmrDataModule, only : dp
|
||||
integer, intent(in) :: n,incx
|
||||
real(dp), intent(in) :: sa
|
||||
real(dp), intent(inout) :: x(*)
|
||||
end subroutine dscal
|
||||
end interface
|
||||
|
||||
end module lsmrblasInterface
|
@ -1,756 +0,0 @@
|
||||
! CODE FOR SURFACE WAVE TOMOGRAPHY USING DISPERSION MEASUREMENTS
|
||||
! VERSION:
|
||||
! 1.0
|
||||
! AUTHOR:
|
||||
! HONGJIAN FANG. fanghj@mail.ustc.edu.cn
|
||||
! PURPOSE:
|
||||
! DIRECTLY INVERT SURFACE WAVE DISPERSION MEASUREMENTS FOR 3-D
|
||||
! STUCTURE WITHOUT THE INTERMEDIATE STEP OF CONSTUCTION THE PHASE
|
||||
! OR GROUP VELOCITY MAPS.
|
||||
! REFERENCE:
|
||||
! Fang, H., Yao, H., Zhang, H., Huang, Y. C., & van der Hilst, R. D.
|
||||
! (2015). Direct inversion of surface wave dispersion for
|
||||
! three-dimensional shallow crustal structure based on ray tracing:
|
||||
! methodology and application. Geophysical Journal International,
|
||||
! 201(3), 1251-1263.
|
||||
! HISTORY:
|
||||
! 2015/01/31 START TO REORGONIZE THE MESSY CODE
|
||||
!
|
||||
|
||||
program SurfTomo
|
||||
use lsmrModule, only:lsmr
|
||||
use lsmrblasInterface, only : dnrm2
|
||||
implicit none
|
||||
|
||||
! VARIABLE DEFINE
|
||||
|
||||
character inputfile*80
|
||||
character logfile*100
|
||||
character outmodel*100
|
||||
character outsyn*100
|
||||
logical ex
|
||||
character dummy*40
|
||||
character datafile*80
|
||||
|
||||
integer nx,ny,nz
|
||||
real goxd,gozd
|
||||
real dvxd,dvzd
|
||||
integer nsrc,nrc
|
||||
real weight,weight0
|
||||
real damp
|
||||
real minthk
|
||||
integer kmax,kmaxRc,kmaxRg,kmaxLc,kmaxLg
|
||||
real*8,dimension(:),allocatable:: tRc,tRg,tLc,tLg
|
||||
real,dimension(:),allocatable:: depz
|
||||
integer itn
|
||||
integer nout
|
||||
integer localSize
|
||||
real mean,std_devs,balances,balanceb
|
||||
integer msurf
|
||||
integer maxlevel,maxleveld
|
||||
real,parameter:: tolr=1e-4
|
||||
real,dimension(:),allocatable:: obst,dsyn,cbst,wt,dtres,dist,datweight
|
||||
real,dimension(:),allocatable:: pvall,depRp,pvRp
|
||||
real sta1_lat,sta1_lon,sta2_lat,sta2_lon
|
||||
real dist1
|
||||
integer dall
|
||||
integer istep
|
||||
real,parameter :: pi=3.1415926535898
|
||||
integer checkstat
|
||||
integer ii,jj,kk
|
||||
real, dimension (:,:), allocatable :: scxf,sczf
|
||||
real, dimension (:,:,:), allocatable :: rcxf,rczf
|
||||
integer,dimension(:,:),allocatable::wavetype,igrt,nrc1
|
||||
integer,dimension(:),allocatable::nsrc1,knum1
|
||||
integer,dimension(:,:),allocatable::periods
|
||||
real,dimension(:),allocatable::rw
|
||||
integer,dimension(:),allocatable::iw,col
|
||||
real,dimension(:),allocatable::dv,norm
|
||||
real,dimension(:,:,:),allocatable::vsf
|
||||
real,dimension(:,:,:),allocatable::vsftrue
|
||||
character strf
|
||||
integer veltp,wavetp
|
||||
real velvalue
|
||||
integer knum,knumo,err
|
||||
integer istep1,istep2
|
||||
integer period
|
||||
integer knumi,srcnum,count1
|
||||
integer HorizonType,VerticalType
|
||||
character line*200
|
||||
integer iter,maxiter
|
||||
integer iiter,initer
|
||||
integer maxnar
|
||||
real acond
|
||||
real anorm
|
||||
real arnorm
|
||||
real rnorm
|
||||
real xnorm
|
||||
character str1
|
||||
real atol,btol
|
||||
real conlim
|
||||
integer istop
|
||||
integer itnlim
|
||||
integer lenrw,leniw
|
||||
integer nar,nar_tmp,nars
|
||||
integer count3,nvz,nvx
|
||||
integer m,maxvp,n
|
||||
integer i,j,k
|
||||
real Minvel,MaxVel
|
||||
real spfra
|
||||
integer domain,normt
|
||||
real noiselevel
|
||||
integer ifsyn
|
||||
integer writepath
|
||||
real averdws
|
||||
real maxnorm
|
||||
real threshold,threshold0
|
||||
|
||||
! OPEN FILES FIRST TO OUTPUT THE PROCESS
|
||||
open(34,file='IterVel.out')
|
||||
nout=36
|
||||
open(nout,file='lsmr.txt')
|
||||
|
||||
! OUTPUT PROGRAM INFOMATION
|
||||
write(*,*)
|
||||
write(*,*),' S U R F T O M O'
|
||||
write(*,*),'PLEASE contact Hongjain Fang &
|
||||
(fanghj@mail.ustc.edu.cn) if you find any bug'
|
||||
write(*,*)
|
||||
|
||||
! READ INPUT FILE
|
||||
if (iargc() < 1) then
|
||||
write(*,*) 'input file [SurfTomo.in(default)]:'
|
||||
read(*,'(a)') inputfile
|
||||
if (len_trim(inputfile) <=1 ) then
|
||||
inputfile = 'SurfTomo.in'
|
||||
else
|
||||
inputfile = inputfile(1:len_trim(inputfile))
|
||||
endif
|
||||
else
|
||||
call getarg(1,inputfile)
|
||||
endif
|
||||
inquire(file = inputfile, exist = ex)
|
||||
if (.not. ex) stop 'unable to open the inputfile'
|
||||
|
||||
open(10,file=inputfile,status='old')
|
||||
read(10,'(a30)')dummy
|
||||
read(10,'(a30)')dummy
|
||||
read(10,'(a30)')dummy
|
||||
read(10,*)datafile
|
||||
read(10,*) nx,ny,nz
|
||||
read(10,*) goxd,gozd
|
||||
read(10,*) dvxd,dvzd
|
||||
read(10,*) nsrc
|
||||
read(10,*) weight0,damp
|
||||
read(10,*) minthk
|
||||
read(10,*) Minvel,Maxvel
|
||||
read(10,*) domain,normt
|
||||
read(10,*) HorizonType,VerticalType
|
||||
read(10,*) maxlevel,maxleveld
|
||||
read(10,*) maxiter,initer
|
||||
read(10,*) spfra
|
||||
read(10,*) kmaxRc
|
||||
write(*,*) 'model origin:latitude,longitue'
|
||||
write(*,'(2f10.4)') goxd,gozd
|
||||
write(*,*) 'grid spacing:latitude,longitue'
|
||||
write(*,'(2f10.4)') dvxd,dvzd
|
||||
write(*,*) 'model dimension:nx,ny,nz'
|
||||
write(*,'(3i5)') nx,ny,nz
|
||||
write(logfile,'(a,a)')trim(inputfile),'.log'
|
||||
open(66,file=logfile)
|
||||
write(66,*)
|
||||
write(66,*),' S U R F T O M O'
|
||||
write(66,*),'PLEASE contact Hongjain Fang &
|
||||
(fanghj@mail.ustc.edu.cn) if you find any bug'
|
||||
write(66,*)
|
||||
write(66,*) 'model origin:latitude,longitue'
|
||||
write(66,'(2f10.4)') goxd,gozd
|
||||
write(66,*) 'grid spacing:latitude,longitue'
|
||||
write(66,'(2f10.4)') dvxd,dvzd
|
||||
write(66,*) 'model dimension:nx,ny,nz'
|
||||
write(66,'(3i5)') nx,ny,nz
|
||||
if(kmaxRc.gt.0)then
|
||||
allocate(tRc(kmaxRc),&
|
||||
stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tRc(i),i=1,kmaxRc)
|
||||
write(*,*)'Rayleigh wave phase velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tRc(i),i=1,kmaxRc)
|
||||
write(66,*)'Rayleigh wave phase velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tRc(i),i=1,kmaxRc)
|
||||
endif
|
||||
read(10,*)kmaxRg
|
||||
if(kmaxRg.gt.0)then
|
||||
allocate(tRg(kmaxRg), stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tRg(i),i=1,kmaxRg)
|
||||
write(*,*)'Rayleigh wave group velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tRg(i),i=1,kmaxRg)
|
||||
write(66,*)'Rayleigh wave group velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tRg(i),i=1,kmaxRg)
|
||||
endif
|
||||
read(10,*)kmaxLc
|
||||
if(kmaxLc.gt.0)then
|
||||
allocate(tLc(kmaxLc), stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tLc(i),i=1,kmaxLc)
|
||||
write(*,*)'Love wave phase velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tLc(i),i=1,kmaxLc)
|
||||
write(66,*)'Love wave phase velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tLc(i),i=1,kmaxLc)
|
||||
endif
|
||||
read(10,*)kmaxLg
|
||||
if(kmaxLg.gt.0)then
|
||||
allocate(tLg(kmaxLg), stat=checkstat)
|
||||
if (checkstat > 0) stop 'error allocating RP'
|
||||
read(10,*)(tLg(i),i=1,kmaxLg)
|
||||
write(*,*)'Love wave group velocity used,periods:(s)'
|
||||
write(*,'(50f6.2)')(tLg(i),i=1,kmaxLg)
|
||||
write(66,*)'Love wave group velocity used,periods:(s)'
|
||||
write(66,'(50f6.2)')(tLg(i),i=1,kmaxLg)
|
||||
endif
|
||||
read(10,*)ifsyn
|
||||
read(10,*)noiselevel
|
||||
read(10,*) threshold0
|
||||
close(10)
|
||||
nrc=nsrc
|
||||
kmax=kmaxRc+kmaxRg+kmaxLc+kmaxLg
|
||||
|
||||
! READ MEASUREMENTS
|
||||
open(unit=87,file=datafile,status='old')
|
||||
allocate(scxf(nsrc,kmax),sczf(nsrc,kmax),&
|
||||
rcxf(nrc,nsrc,kmax),rczf(nrc,nsrc,kmax),stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate'
|
||||
endif
|
||||
allocate(periods(nsrc,kmax),wavetype(nsrc,kmax),&
|
||||
nrc1(nsrc,kmax),nsrc1(kmax),knum1(kmax),&
|
||||
igrt(nsrc,kmax),stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate'
|
||||
endif
|
||||
allocate(obst(nrc*nsrc*kmax),dist(nrc*nsrc*kmax),&
|
||||
stat=checkstat)
|
||||
allocate(pvall(nrc*nsrc*kmax),depRp(nrc*nsrc*kmax),&
|
||||
pvRp(nrc*nsrc*kmax),stat=checkstat)
|
||||
IF(checkstat > 0)THEN
|
||||
write(6,*)'error with allocate'
|
||||
ENDIF
|
||||
istep=0
|
||||
istep2=0
|
||||
dall=0
|
||||
knumo=12345
|
||||
knum=0
|
||||
istep1=0
|
||||
do
|
||||
read(87,'(a)',iostat=err) line
|
||||
if(err.eq.0) then
|
||||
if(line(1:1).eq.'#') then
|
||||
read(line,*) str1,sta1_lat,sta1_lon,period,wavetp,veltp
|
||||
if(wavetp.eq.2.and.veltp.eq.0) knum=period
|
||||
if(wavetp.eq.2.and.veltp.eq.1) knum=kmaxRc+period
|
||||
if(wavetp.eq.1.and.veltp.eq.0) knum=kmaxRg+kmaxRc+period
|
||||
if(wavetp.eq.1.and.veltp.eq.1) knum=kmaxLc+kmaxRg+&
|
||||
kmaxRc+period
|
||||
if(knum.ne.knumo) then
|
||||
istep=0
|
||||
istep2=istep2+1
|
||||
endif
|
||||
istep=istep+1
|
||||
istep1=0
|
||||
sta1_lat=(90.0-sta1_lat)*pi/180.0
|
||||
sta1_lon=sta1_lon*pi/180.0
|
||||
scxf(istep,knum)=sta1_lat
|
||||
sczf(istep,knum)=sta1_lon
|
||||
periods(istep,knum)=period
|
||||
wavetype(istep,knum)=wavetp
|
||||
igrt(istep,knum)=veltp
|
||||
nsrc1(knum)=istep
|
||||
knum1(istep2)=knum
|
||||
knumo=knum
|
||||
else
|
||||
read(line,*) sta2_lat,sta2_lon,velvalue
|
||||
istep1=istep1+1
|
||||
dall=dall+1
|
||||
sta2_lat=(90.0-sta2_lat)*pi/180.0
|
||||
sta2_lon=sta2_lon*pi/180.0
|
||||
rcxf(istep1,istep,knum)=sta2_lat
|
||||
rczf(istep1,istep,knum)=sta2_lon
|
||||
call delsph(sta1_lat,sta1_lon,sta2_lat,sta2_lon,dist1)
|
||||
dist(dall)=dist1
|
||||
obst(dall)=dist1/velvalue
|
||||
pvall(dall)=velvalue
|
||||
nrc1(istep,knum)=istep1
|
||||
endif
|
||||
else
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
close(87)
|
||||
allocate(depz(nz), stat=checkstat)
|
||||
maxnar = dall*nx*ny*nz*spfra!sparsity fraction
|
||||
maxvp = (nx-2)*(ny-2)*(nz-1)
|
||||
allocate(dv(maxvp), stat=checkstat)
|
||||
allocate(norm(maxvp), stat=checkstat)
|
||||
allocate(vsf(nx,ny,nz), stat=checkstat)
|
||||
allocate(vsftrue(nx,ny,nz), stat=checkstat)
|
||||
|
||||
allocate(rw(maxnar), stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate: real rw'
|
||||
endif
|
||||
allocate(iw(2*maxnar+1), stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate: integer iw'
|
||||
endif
|
||||
allocate(col(maxnar), stat=checkstat)
|
||||
if(checkstat > 0)then
|
||||
write(6,*)'error with allocate: integer iw'
|
||||
endif
|
||||
allocate(cbst(dall+maxvp),dsyn(dall),datweight(dall),wt(dall+maxvp),dtres(dall+maxvp),&
|
||||
stat=checkstat)
|
||||
|
||||
! MEASUREMENTS STATISTICS AND READ INITIAL MODEL
|
||||
write(*,'(a,i7)') 'Number of all measurements',dall
|
||||
|
||||
open(10,file='MOD',status='old')
|
||||
read(10,*) (depz(i),i=1,nz)
|
||||
do k = 1,nz
|
||||
do j = 1,ny
|
||||
read(10,*)(vsf(i,j,k),i=1,nx)
|
||||
enddo
|
||||
enddo
|
||||
close(10)
|
||||
write(*,*) 'grid points in depth direction:(km)'
|
||||
write(*,'(50f6.2)') depz
|
||||
|
||||
|
||||
|
||||
! CHECKERBOARD TEST
|
||||
if (ifsyn == 1) then
|
||||
write(*,*) 'Checkerboard Resolution Test Begin'
|
||||
vsftrue = vsf
|
||||
|
||||
open(11,file='MOD.true',status='old')
|
||||
do k = 1,nz
|
||||
do j = 1,ny
|
||||
read(11,*) (vsftrue(i,j,k),i=1,nx)
|
||||
enddo
|
||||
enddo
|
||||
close(11)
|
||||
|
||||
call synthetic(nx,ny,nz,maxvp,vsftrue,obst,&
|
||||
goxd,gozd,dvxd,dvzd,kmaxRc,kmaxRg,kmaxLc,kmaxLg,&
|
||||
tRc,tRg,tLc,tLg,wavetype,igrt,periods,depz,minthk,&
|
||||
scxf,sczf,rcxf,rczf,nrc1,nsrc1,knum1,kmax,&
|
||||
nsrc,nrc,noiselevel)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
! ITERATE UNTILL CONVERGE
|
||||
writepath = 0
|
||||
do iter = 1,maxiter
|
||||
iw = 0
|
||||
rw = 0.0
|
||||
col = 0
|
||||
|
||||
! COMPUTE SENSITIVITY MATRIX
|
||||
if (iter == maxiter) then
|
||||
writepath = 1
|
||||
open(40,file='raypath.out')
|
||||
endif
|
||||
write(*,*) 'computing sensitivity matrix...'
|
||||
call CalSurfG(nx,ny,nz,maxvp,vsf,iw,rw,col,dsyn,&
|
||||
goxd,gozd,dvxd,dvzd,kmaxRc,kmaxRg,kmaxLc,kmaxLg,&
|
||||
tRc,tRg,tLc,tLg,wavetype,igrt,periods,depz,minthk,&
|
||||
scxf,sczf,rcxf,rczf,nrc1,nsrc1,knum1,kmax,&
|
||||
nsrc,nrc,nar,domain,&
|
||||
maxlevel,maxleveld,HorizonType,VerticalType,writepath)
|
||||
|
||||
do i = 1,dall
|
||||
cbst(i) = obst(i) - dsyn(i)
|
||||
enddo
|
||||
|
||||
threshold = threshold0+(maxiter/2-iter)/3*0.5
|
||||
do i = 1,dall
|
||||
datweight(i) = 1.0
|
||||
if(abs(cbst(i)) > threshold) then
|
||||
datweight(i) = exp(-(abs(cbst(i))-threshold))
|
||||
endif
|
||||
cbst(i) = cbst(i)*datweight(i)
|
||||
enddo
|
||||
|
||||
do i = 1,nar
|
||||
rw(i) = rw(i)*datweight(iw(1+i))
|
||||
enddo
|
||||
|
||||
norm=0
|
||||
do i=1,nar
|
||||
norm(col(i))=norm(col(i))+abs(rw(i))
|
||||
enddo
|
||||
averdws=0
|
||||
maxnorm=0
|
||||
do i=1,maxvp
|
||||
averdws = averdws+norm(i)
|
||||
if(norm(i)>maxnorm) maxnorm=norm(i)
|
||||
enddo
|
||||
averdws=averdws/maxvp
|
||||
write(66,*)'Maximum and Average DWS values:',maxnorm,averdws
|
||||
write(66,*)'Threshold is:',threshold
|
||||
|
||||
! WRITE OUT RESIDUAL FOR THE FIRST AND LAST ITERATION
|
||||
if(iter.eq.1) then
|
||||
open(88,file='residualFirst.dat')
|
||||
do i=1,dall
|
||||
write(88,*) dist(i),dsyn(i),obst(i), &
|
||||
dsyn(i)*datweight(i),obst(i)*datweight(i),datweight(i)
|
||||
enddo
|
||||
close(88)
|
||||
endif
|
||||
if(iter.eq.maxiter) then
|
||||
open(88,file='residualLast.dat')
|
||||
do i=1,dall
|
||||
write(88,*) dist(i),dsyn(i),obst(i), &
|
||||
dsyn(i)*datweight(i),obst(i)*datweight(i),datweight(i)
|
||||
enddo
|
||||
close(88)
|
||||
endif
|
||||
|
||||
|
||||
! ADDING REGULARIZATION TERM
|
||||
weight=dnrm2(dall,cbst,1)**2/dall*weight0
|
||||
nar_tmp=nar
|
||||
nars=0
|
||||
! if (domain == 0 .and. normt==0) then
|
||||
if (domain == 0) then
|
||||
do i=1,maxvp
|
||||
rw(nar+i)=weight
|
||||
iw(1+nar+i)=dall+i
|
||||
col(nar+i)=i
|
||||
cbst(dall+i)=0
|
||||
enddo
|
||||
nar = nar + maxvp
|
||||
m = dall + maxvp
|
||||
n = maxvp
|
||||
! elseif(domain == 0 .and. normt/=0) then
|
||||
! do i=1,maxvp
|
||||
! rw(nar+i)=weight
|
||||
! iw(1+nar+i)=dall+i
|
||||
! col(nar+i)=i
|
||||
! cbst(dall+i)=0
|
||||
! enddo
|
||||
! nar = nar + maxvp
|
||||
! m = dall + maxvp
|
||||
! n = maxvp
|
||||
else
|
||||
count3=0
|
||||
nvz=ny-2
|
||||
nvx=nx-2
|
||||
do k=1,nz-1
|
||||
do j=1,nvz
|
||||
do i=1,nvx
|
||||
if(i==1.or.i==nvx.or.j==1.or.j==nvz.or.k==1.or.k==nz-1)then
|
||||
count3=count3+1
|
||||
col(nar+1)=(k-1)*nvz*nvx+(j-1)*nvx+i
|
||||
rw(nar+1)=2.0*weight
|
||||
iw(1+nar+1)=dall+count3
|
||||
cbst(dall+count3)=0
|
||||
nar=nar+1
|
||||
else
|
||||
count3=count3+1
|
||||
col(nar+1)=(k-1)*nvz*nvx+(j-1)*nvx+i
|
||||
rw(nar+1)=6.0*weight
|
||||
iw(1+nar+1)=dall+count3
|
||||
rw(nar+2)=-1.0*weight
|
||||
iw(1+nar+2)=dall+count3
|
||||
col(nar+2)=(k-1)*nvz*nvx+(j-1)*nvx+i-1
|
||||
rw(nar+3)=-1.0*weight
|
||||
iw(1+nar+3)=dall+count3
|
||||
col(nar+3)=(k-1)*nvz*nvx+(j-1)*nvx+i+1
|
||||
rw(nar+4)=-1.0*weight
|
||||
iw(1+nar+4)=dall+count3
|
||||
col(nar+4)=(k-1)*nvz*nvx+(j-2)*nvx+i
|
||||
rw(nar+5)=-1.0*weight
|
||||
iw(1+nar+5)=dall+count3
|
||||
col(nar+5)=(k-1)*nvz*nvx+j*nvx+i
|
||||
rw(nar+6)=-1.0*weight
|
||||
iw(1+nar+6)=dall+count3
|
||||
col(nar+6)=(k-2)*nvz*nvx+(j-1)*nvx+i
|
||||
rw(nar+7)=-1.0*weight
|
||||
iw(1+nar+7)=dall+count3
|
||||
col(nar+7)=k*nvz*nvx+(j-1)*nvx+i
|
||||
cbst(dall+count3)=0
|
||||
nar=nar+7
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
m = dall + count3
|
||||
n = maxvp
|
||||
nars = nar - nar_tmp
|
||||
rw(nar+1:nar+nars) = rw(nar_tmp+1:nar)
|
||||
endif
|
||||
|
||||
iw(1)=nar
|
||||
do i=1,nar
|
||||
iw(1+nar+i)=col(i)
|
||||
enddo
|
||||
if (nar > maxnar) stop 'increase sparsity fraction(spfra)'
|
||||
|
||||
! CALLING IRLS TO SOLVE THE PROBLEM
|
||||
|
||||
leniw = 2*nar+1
|
||||
lenrw = nar
|
||||
dv = 0
|
||||
atol = 1e-3
|
||||
btol = 1e-3
|
||||
conlim = 1200
|
||||
itnlim = 1000
|
||||
istop = 0
|
||||
anorm = 0.0
|
||||
acond = 0.0
|
||||
arnorm = 0.0
|
||||
xnorm = 0.0
|
||||
localSize = n/4
|
||||
|
||||
call LSMR(m, n, leniw, lenrw,iw,rw,cbst, damp,&
|
||||
atol, btol, conlim, itnlim, localSize, nout,&
|
||||
dv, istop, itn, anorm, acond, rnorm, arnorm, xnorm)
|
||||
if(istop==3) print*,'istop = 3, large condition number'
|
||||
|
||||
|
||||
if (domain == 0.and.normt==0) then
|
||||
do iiter = 1, initer-1
|
||||
dtres=-cbst
|
||||
call aprod(1,m,n,dv,dtres,leniw,lenrw,iw,rw)
|
||||
do i=1,m
|
||||
if(abs(dtres(i)).lt.tolr) then
|
||||
wt(i)= 1.0/sqrt(abs(tolr))
|
||||
else
|
||||
wt(i)=1.0/sqrt(abs(dtres(i)))
|
||||
endif
|
||||
enddo
|
||||
do i=1,nar
|
||||
rw(i)=rw(i)*wt(iw(i+1))
|
||||
enddo
|
||||
do i=1,m
|
||||
dtres(i)=cbst(i)*wt(i)
|
||||
enddo
|
||||
|
||||
dv = 0
|
||||
atol = 1e-3
|
||||
btol = 1e-3
|
||||
conlim = 1200
|
||||
itnlim = 1000
|
||||
istop = 0
|
||||
anorm = 0.0
|
||||
acond = 0.0
|
||||
arnorm = 0.0
|
||||
xnorm = 0.0
|
||||
|
||||
|
||||
call LSMR(m, n, leniw, lenrw,iw,rw,dtres, damp,&
|
||||
atol, btol, conlim, itnlim, localSize, nout,&
|
||||
dv, istop, itn, anorm, acond, rnorm, arnorm, xnorm)
|
||||
if(istop==3) print*,'istop = 3, large condition number'
|
||||
|
||||
do i=1,nar
|
||||
rw(i)=rw(i)/wt(iw(i+1))
|
||||
enddo
|
||||
|
||||
enddo ! finish inter interations for IRLS
|
||||
endif
|
||||
|
||||
|
||||
if(domain==0.and.normt/=0) then
|
||||
do iiter = 1, initer-1
|
||||
do i=1,n
|
||||
if (abs(dv(i)).lt.tolr) then
|
||||
rw(nar_tmp+i)=1.0/sqrt(tolr)*weight
|
||||
else
|
||||
rw(nar_tmp+i)=sqrt(1.0/abs(dv(i)))*weight
|
||||
endif
|
||||
enddo
|
||||
dv = 0
|
||||
atol = 1e-3
|
||||
btol = 1e-3
|
||||
conlim = 1200
|
||||
itnlim = 1000
|
||||
istop = 0
|
||||
anorm = 0.0
|
||||
acond = 0.0
|
||||
arnorm = 0.0
|
||||
xnorm = 0.0
|
||||
|
||||
call LSMR(m, n, leniw, lenrw,iw,rw,cbst, damp,&
|
||||
atol, btol, conlim, itnlim, localSize, nout,&
|
||||
dv, istop, itn, anorm, acond, rnorm, arnorm, xnorm)
|
||||
if(istop==3) print*,'istop = 3, large condition number'
|
||||
enddo
|
||||
endif
|
||||
|
||||
|
||||
|
||||
if (domain/=0)then
|
||||
do iiter = 1,initer-1
|
||||
|
||||
dtres = 0
|
||||
call aprod(1,m,n,dv,dtres,leniw,lenrw,iw,rw)
|
||||
do i = nar_tmp+1,nar
|
||||
if(abs(dtres(iw(1+i)))<tolr) then
|
||||
rw(i)=1/sqrt(tolr)*rw(i+nars)
|
||||
else
|
||||
rw(i)=sqrt(1.0/abs(dtres(iw(1+i))))*rw(i+nars)
|
||||
endif
|
||||
enddo
|
||||
dv = 0
|
||||
atol = 1e-3
|
||||
btol = 1e-3
|
||||
conlim = 1200
|
||||
itnlim = 1000
|
||||
istop = 0
|
||||
anorm = 0.0
|
||||
acond = 0.0
|
||||
arnorm = 0.0
|
||||
xnorm = 0.0
|
||||
|
||||
|
||||
call LSMR(m, n, leniw, lenrw,iw,rw,cbst, damp,&
|
||||
atol, btol, conlim, itnlim, localSize, nout,&
|
||||
dv, istop, itn, anorm, acond, rnorm, arnorm, xnorm)
|
||||
if(istop==3) print*,'istop = 3, large condition number'
|
||||
|
||||
enddo
|
||||
endif
|
||||
|
||||
mean = sum(cbst(1:dall))/dall
|
||||
std_devs = sqrt(sum(cbst(1:dall)**2)/dall - mean**2)
|
||||
write(*,'(i2,a)'),iter,'th iteration...'
|
||||
write(*,'(a,f7.3)'),'weight is:',weight
|
||||
write(*,'(a,f8.1,a,f8.2,a,f8.3)'),'mean,std_devs and chi sqrue of &
|
||||
residual: ',mean*1000,'ms ',1000*std_devs,'ms ',&
|
||||
dnrm2(dall,cbst,1)**2/sqrt(dall)
|
||||
write(66,'(i2,a)'),iter,'th iteration...'
|
||||
write(66,'(a,f7.3)'),'weight is:',weight
|
||||
write(66,'(a,f8.1,a,f8.2,a,f8.3)'),'mean,std_devs and chi sqrue of &
|
||||
residual: ',mean*1000,'ms ',1000*std_devs,'ms ',&
|
||||
dnrm2(dall,cbst,1)**2/sqrt(dall)
|
||||
|
||||
if (domain == 0) then
|
||||
call invwavetrans(nx-2,ny-2,nz-1,dv,maxlevel,maxleveld,&
|
||||
HorizonType,VerticalType)
|
||||
endif
|
||||
|
||||
write(*,'(a,2f7.4)'),'min and max velocity variation ',&
|
||||
minval(dv),maxval(dv)
|
||||
write(66,'(a,2f7.4)'),'min and max velocity variation ',&
|
||||
minval(dv),maxval(dv)
|
||||
|
||||
do k=1,nz-1
|
||||
do j=1,ny-2
|
||||
do i=1,nx-2
|
||||
if(dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i).ge.0.500) then
|
||||
dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i)=0.500
|
||||
endif
|
||||
if(dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i).le.-0.500) then
|
||||
dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i)=-0.500
|
||||
endif
|
||||
vsf(i+1,j+1,k)=vsf(i+1,j+1,k)+dv((k-1)*(nx-2)*(ny-2)+(j-1)*(nx-2)+i)
|
||||
if(vsf(i+1,j+1,k).lt.Minvel) vsf(i+1,j+1,k)=Minvel
|
||||
if(vsf(i+1,j+1,k).gt.Maxvel) vsf(i+1,j+1,k)=Maxvel
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
write(34,*)',OUTPUT S VELOCITY AT ITERATION',iter
|
||||
do k=1,nz
|
||||
do j=1,ny
|
||||
write(34,'(100f7.3)') (vsf(i,j,k),i=1,nx)
|
||||
enddo
|
||||
enddo
|
||||
write(34,*)',OUTPUT DWS AT ITERATION',iter
|
||||
do k=1,nz-1
|
||||
do j=2,ny-1
|
||||
write(34,'(100f8.1)') (norm((k-1)*(ny-2)*(nx-2)+(j-2)*(nx-2)+i-1),i=2,nx-1)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
enddo !end iteration
|
||||
|
||||
! OUTPUT THE VELOCITY MODEL
|
||||
|
||||
write(*,*),'Program finishes successfully'
|
||||
write(66,*),'Program finishes successfully'
|
||||
|
||||
if(ifsyn == 1) then
|
||||
open(65,file='Vs_model.real')
|
||||
write(outsyn,'(a,a)') trim(inputfile),'Syn.dat'
|
||||
open(63,file=outsyn)
|
||||
do k=1,nz-1
|
||||
do j=1,ny-2
|
||||
do i=1,nx-2
|
||||
write(65,'(5f8.4)') gozd+(j-1)*dvzd,goxd-(i-1)*dvxd,depz(k),vsftrue(i,j,k)
|
||||
write(63,'(5f8.4)') gozd+(j-1)*dvzd,goxd-(i-1)*dvxd,depz(k),vsf(i,j,k)
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
close(65)
|
||||
close(63)
|
||||
write(*,*),'Output True velocity model &
|
||||
to Vs_model.real'
|
||||
write(*,*),'Output inverted shear velocity model &
|
||||
to ',outsyn
|
||||
write(66,*),'Output True velocity model &
|
||||
to Vs_model.real'
|
||||
write(66,*),'Output inverted shear velocity model &
|
||||
to ',outsyn
|
||||
else
|
||||
write(outmodel,'(a,a)') trim(inputfile),'Measure.dat'
|
||||
open(64,file=outmodel)
|
||||
do k=1,nz-1
|
||||
do j=1,ny-2
|
||||
do i=1,nx-2
|
||||
write(64,'(5f8.4)') gozd+(j-1)*dvzd,goxd-(i-1)*dvxd,depz(k),vsf(i,j,k)
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
close(64)
|
||||
write(*,*),'Output inverted shear velocity model &
|
||||
to ',outmodel
|
||||
write(66,*),'Output inverted shear velocity model &
|
||||
to ',outmodel
|
||||
endif
|
||||
|
||||
close(34)
|
||||
close(40)
|
||||
close(nout) !close lsmr.txt
|
||||
close(66) !close surf_tomo.log
|
||||
deallocate(obst)
|
||||
deallocate(dsyn)
|
||||
deallocate(dist)
|
||||
deallocate(depz)
|
||||
deallocate(scxf,sczf)
|
||||
deallocate(rcxf,rczf)
|
||||
deallocate(wavetype,igrt,nrc1)
|
||||
deallocate(nsrc1,knum1,periods)
|
||||
deallocate(rw)
|
||||
deallocate(iw,col)
|
||||
deallocate(cbst,wt,dtres,datweight)
|
||||
deallocate(dv)
|
||||
deallocate(norm)
|
||||
deallocate(vsf)
|
||||
deallocate(vsftrue)
|
||||
if(kmaxRc.gt.0) then
|
||||
deallocate(tRc)
|
||||
endif
|
||||
if(kmaxRg.gt.0) then
|
||||
deallocate(tRg)
|
||||
endif
|
||||
if(kmaxLc.gt.0) then
|
||||
deallocate(tLc)
|
||||
endif
|
||||
if(kmaxLg.gt.0) then
|
||||
deallocate(tLg)
|
||||
endif
|
||||
|
||||
end program
|
@ -1,21 +0,0 @@
|
||||
subroutine merge1(vec,n)
|
||||
implicit none
|
||||
integer n
|
||||
real vec(n)
|
||||
|
||||
integer half,start,endt
|
||||
integer i
|
||||
real tmp
|
||||
half=n/2
|
||||
start=half
|
||||
endt=half+1
|
||||
do while(start.gt.1)
|
||||
do i=start,endt-1,2
|
||||
tmp=vec(i)
|
||||
vec(i)=vec(i+1)
|
||||
vec(i+1)=tmp
|
||||
enddo
|
||||
start=start-1
|
||||
endt=endt+1
|
||||
enddo
|
||||
end subroutine
|
@ -1,24 +0,0 @@
|
||||
subroutine split(vec,n)
|
||||
implicit none
|
||||
integer n
|
||||
real vec(n)
|
||||
|
||||
!c local
|
||||
integer start,endt,i,j
|
||||
real tmp
|
||||
start=2
|
||||
!if(mod(n,2).ne.0) then
|
||||
! endt=n-1
|
||||
!else
|
||||
endt=n
|
||||
!endif
|
||||
do while (start.lt.endt)
|
||||
do i=start,endt-1,2
|
||||
tmp=vec(i)
|
||||
vec(i)=vec(i+1)
|
||||
vec(i+1)=tmp
|
||||
end do
|
||||
start=start+1
|
||||
endt=endt-1
|
||||
enddo
|
||||
end subroutine
|
File diff suppressed because it is too large
Load Diff
@ -1,113 +0,0 @@
|
||||
subroutine transformD8(a,n)
|
||||
implicit none
|
||||
integer n
|
||||
real a(n)
|
||||
|
||||
integer i,j
|
||||
integer half
|
||||
real tmp(n)
|
||||
real*8 h(8),g(8)
|
||||
data h/-0.010597401784997278,&
|
||||
0.032883011666982945,&
|
||||
0.030841381835986965,&
|
||||
-0.18703481171888114,&
|
||||
-0.02798376941698385,&
|
||||
0.6308807679295904,&
|
||||
0.7148465705525415,&
|
||||
0.23037781330885523/
|
||||
|
||||
|
||||
data g/-0.23037781330885523,&
|
||||
0.7148465705525415,&
|
||||
-0.6308807679295904,&
|
||||
-0.02798376941698385,&
|
||||
0.18703481171888114,&
|
||||
0.030841381835986965,&
|
||||
-0.032883011666982945,&
|
||||
-0.010597401784997278/
|
||||
|
||||
half=n/2
|
||||
i=1
|
||||
tmp=0
|
||||
do j=1,n-7,2
|
||||
tmp(i)=a(j)*h(1)+a(j+1)*h(2)+a(j+2)*h(3)+a(j+3)*h(4)+a(j+4)*h(5) &
|
||||
+a(j+5)*h(6)+a(j+6)*h(7)+a(j+7)*h(8)
|
||||
tmp(i+half)=a(j)*g(1)+a(j+1)*g(2)+a(j+2)*g(3)+a(j+3)*g(4) &
|
||||
+a(j+4)*g(5)+a(j+5)*g(6)+a(j+6)*g(7)+a(j+7)*g(8)
|
||||
i=i+1
|
||||
enddo
|
||||
|
||||
tmp(i)=a(n-5)*h(1)+a(n-4)*h(2)+a(n-3)*h(3)+a(n-2)*h(4)+a(n-1)*h(5) &
|
||||
+a(n)*h(6)+a(1)*h(7)+a(2)*h(8)
|
||||
tmp(i+half)=a(n-5)*g(1)+a(n-4)*g(2)+a(n-3)*g(3)+a(n-2)*g(4) &
|
||||
+a(n-1)*g(5) +a(n)*g(6)+a(1)*g(7)+a(2)*g(8)
|
||||
tmp(i+1)=a(n-3)*h(1)+a(n-2)*h(2)+a(n-1)*h(3)+a(n)*h(4)+a(1)*h(5) &
|
||||
+a(2)*h(6)+a(3)*h(7)+a(4)*h(8)
|
||||
tmp(i+1+half)=a(n-3)*g(1)+a(n-2)*g(2)+a(n-1)*g(3)+a(n)*g(4) &
|
||||
+a(1)*g(5)+a(2)*g(6)+a(3)*g(7)+a(4)*g(8)
|
||||
tmp(i+2)=a(n-1)*h(1)+a(n)*h(2)+a(1)*h(3)+a(2)*h(4)+a(3)*h(5) &
|
||||
+a(4)*h(6)+a(5)*h(7)+a(6)*h(8)
|
||||
tmp(i+2+half)=a(n-1)*g(1)+a(n)*g(2)+a(1)*g(3)+a(2)*g(4)+a(3)*g(5) &
|
||||
+a(4)*g(6)+a(5)*g(7)+a(6)*g(8)
|
||||
|
||||
do i=1,n
|
||||
a(i)=tmp(i)
|
||||
enddo
|
||||
|
||||
end subroutine
|
||||
|
||||
subroutine invTransformD8(a,n)
|
||||
implicit none
|
||||
integer n
|
||||
real a(n)
|
||||
|
||||
real tmp(n)
|
||||
real*8 Ih(8),Ig(8)
|
||||
integer half
|
||||
integer i,j
|
||||
data Ih/0.23037781330885523,&
|
||||
0.7148465705525415,&
|
||||
0.6308807679295904,&
|
||||
-0.02798376941698385,&
|
||||
-0.18703481171888114,&
|
||||
0.030841381835986965,&
|
||||
0.032883011666982945,&
|
||||
-0.010597401784997278/
|
||||
data Ig/-0.010597401784997278,&
|
||||
-0.032883011666982945,&
|
||||
0.030841381835986965,&
|
||||
0.18703481171888114,&
|
||||
-0.02798376941698385,&
|
||||
-0.6308807679295904,&
|
||||
0.7148465705525415,&
|
||||
-0.23037781330885523/
|
||||
|
||||
half=n/2
|
||||
tmp(2)=a(half-2)*Ih(1)+a(n-2)*Ig(1)+a(half-1)*Ih(3)+a(n-1)*Ig(3) &
|
||||
+a(half)*Ih(5)+a(n)*Ig(5)+a(1)*Ih(7)+a(half+1)*Ig(7)
|
||||
tmp(1)=a(half-2)*Ih(2)+a(n-2)*Ig(2)+a(half-1)*Ih(4)+a(n-1)*Ig(4) &
|
||||
+a(half)*Ih(6)+a(n)*Ig(6)+a(1)*Ih(8)+a(half+1)*Ig(8)
|
||||
tmp(4)=a(half-1)*Ih(1)+a(n-1)*Ig(1)+a(half)*Ih(3)+a(n)*Ig(3) &
|
||||
+a(1)*Ih(5)+a(half+1)*Ig(5)+a(2)*Ih(7)+a(half+2)*Ig(7)
|
||||
tmp(3)=a(half-1)*Ih(2)+a(n-1)*Ig(2)+a(half)*Ih(4)+a(n)*Ig(4) &
|
||||
+a(1)*Ih(6)+a(half+1)*Ig(6)+a(2)*Ih(8)+a(half+2)*Ig(8)
|
||||
tmp(6)=a(half)*Ih(1)+a(n)*Ig(1)+a(1)*Ih(3)+a(half+1)*Ig(3) &
|
||||
+a(2)*Ih(5)+a(half+2)*Ig(5)+a(3)*Ih(7)+a(half+3)*Ig(7)
|
||||
tmp(5)=a(half)*Ih(2)+a(n)*Ig(2)+a(1)*Ih(4)+a(half+1)*Ig(4) &
|
||||
+a(2)*Ih(6)+a(half+2)*Ig(6)+a(3)*Ih(8)+a(half+3)*Ig(8)
|
||||
|
||||
j=6
|
||||
do i=1,half-3
|
||||
j=j+1
|
||||
tmp(j)=a(i)*Ih(2)+a(i+half)*Ig(2)+a(i+1)*Ih(4)+a(i+1+half)*Ig(4) &
|
||||
+a(i+2)*Ih(6)+a(i+2+half)*Ig(6)+a(i+3)*Ih(8)+a(i+3+half)*Ig(8)
|
||||
j=j+1
|
||||
tmp(j)=a(i)*Ih(1)+a(i+half)*Ig(1)+a(i+1)*Ih(3)+a(i+1+half)*Ig(3) &
|
||||
+a(i+2)*Ih(5)+a(i+2+half)*Ig(5)+a(i+3)*Ih(7)+a(i+3+half)*Ig(7)
|
||||
enddo
|
||||
|
||||
do i=1,n
|
||||
a(i)=tmp(i)
|
||||
enddo
|
||||
|
||||
end subroutine
|
@ -1,90 +0,0 @@
|
||||
subroutine wavelettrans(nx,ny,nz,row,maxlevel,maxleveld,HorizonType,VerticalType)
|
||||
use omp_lib
|
||||
implicit none
|
||||
integer nx,ny,nz,maxlevel,maxleveld
|
||||
real row(*)
|
||||
|
||||
integer j,k
|
||||
real fxs(nx),fzs(nz),fys(ny)
|
||||
integer HorizonType,VerticalType
|
||||
! if(PorS == 1 .or. PorS == 3) then
|
||||
!!$omp parallel &
|
||||
!!$omp default(private) &
|
||||
!!$omp shared(nz,ny,nx,maxlevel,row,HorizonType)
|
||||
!!$omp do
|
||||
! do k=1,nz
|
||||
! do j=1,ny
|
||||
! fxp=row(1+(j-1)*nx+(k-1)*nx*ny:nx+(j-1)*nx+(k-1)*nx*ny)
|
||||
! call forwardtrans(fxp,nx,maxlevel,HorizonType)
|
||||
! row(1+(j-1)*nx+(k-1)*nx*ny:nx+(j-1)*nx+(k-1)*nx*ny)=fxp
|
||||
! enddo
|
||||
! enddo
|
||||
!!$omp end do
|
||||
!!$omp end parallel
|
||||
!!$omp parallel &
|
||||
!!$omp default(private) &
|
||||
!!$omp shared(nz,ny,nx,maxlevel,row,HorizonType)
|
||||
!!$omp do
|
||||
! do k=1,nz
|
||||
! do j=1,nx
|
||||
! fyp=row(j+(k-1)*nx*ny:j+(ny-1)*nx+(k-1)*nx*ny:nx)
|
||||
! call forwardtrans(fyp,ny,maxlevel,HorizonType)
|
||||
! row(j+(k-1)*nx*ny:j+(ny-1)*nx+(k-1)*nx*ny:nx)=fyp
|
||||
! enddo
|
||||
! enddo
|
||||
!!$omp end do
|
||||
!!$omp end parallel
|
||||
!!$omp parallel &
|
||||
!!$omp default(private) &
|
||||
!!$omp shared(nz,ny,nx,maxleveld,row,VerticalType)
|
||||
!!$omp do
|
||||
! do k=1,ny
|
||||
! do j=1,nx
|
||||
! fzp=row(j+(k-1)*nx:j+(k-1)*nx+(nz-1)*nx*ny:nx*ny)
|
||||
! call forwardtrans(fzp,nz,maxleveld,VerticalType)
|
||||
! row(j+(k-1)*nx:j+(k-1)*nx+(nz-1)*nx*ny:nx*ny)=fzp
|
||||
! enddo
|
||||
! enddo
|
||||
!!$omp end do
|
||||
!!$omp end parallel
|
||||
! endif
|
||||
!$omp parallel &
|
||||
!$omp default(private) &
|
||||
!$omp shared(nz,ny,nx,maxlevel,row,HorizonType)
|
||||
!$omp do
|
||||
do k=1,nz
|
||||
do j=1,ny
|
||||
fxs=row(1+(j-1)*nx+(k-1)*nx*ny:nx+(j-1)*nx+(k-1)*nx*ny)
|
||||
call forwardtrans(fxs,nx,maxlevel,HorizonType)
|
||||
row(1+(j-1)*nx+(k-1)*nx*ny:nx+(j-1)*nx+(k-1)*nx*ny)=fxs
|
||||
enddo
|
||||
enddo
|
||||
!$omp end do
|
||||
!$omp end parallel
|
||||
!$omp parallel &
|
||||
!$omp default(private) &
|
||||
!$omp shared(nz,ny,nx,maxlevel,row,HorizonType)
|
||||
!$omp do
|
||||
do k=1,nz
|
||||
do j=1,nx
|
||||
fys=row(j+(k-1)*nx*ny:j+(ny-1)*nx+(k-1)*nx*ny:nx)
|
||||
call forwardtrans(fys,ny,maxlevel,HorizonType)
|
||||
row(j+(k-1)*nx*ny:j+(ny-1)*nx+(k-1)*nx*ny:nx)=fys
|
||||
enddo
|
||||
enddo
|
||||
!$omp end do
|
||||
!$omp end parallel
|
||||
!$omp parallel &
|
||||
!$omp default(private) &
|
||||
!$omp shared(nz,ny,nx,maxleveld,row,VerticalType)
|
||||
!$omp do
|
||||
do k=1,ny
|
||||
do j=1,nx
|
||||
fzs=row(j+(k-1)*nx:j+(k-1)*nx+(nz-1)*nx*ny:nx*ny)
|
||||
call forwardtrans(fzs,nz,maxleveld,VerticalType)
|
||||
row(j+(k-1)*nx:j+(k-1)*nx+(nz-1)*nx*ny:nx*ny)=fzs
|
||||
enddo
|
||||
enddo
|
||||
!$omp end do
|
||||
!$omp end parallel
|
||||
end subroutine
|
Loading…
Reference in New Issue
Block a user