Gents,
I cant thank you enough for the inputs and comments (steven, louisa,Les, Dick, Richard, Louis,dpb). I've been juggling this with other stuff so I can accomodate your inputs as much as possible. based on you inputs, as richard says, the improvement in the processing speed is not enough to reach my target, although i didnt expect it to be quite significant sometimes over a small change. For example, just putting several things outside the loop can drop the total time by 4 secs for a small array..this could be of great significance when applied to much larger input arrays.
Yesterday, when DPB mention about profile I immediately follow his suggestion and I found out that the longest time took place here:
j=0
do
j=j + 1
ome=delint*j
call kspect(n,ome,taup,siga,sigb,Hs,conalpha,alpha,gamma,depth,see,suu)
if ((max(see(i), suu(i)).lt.cutint).and.(ome.gt.omep)) exit
ttt1=half*(suuold + suu(i))*delint
fm0(i)=fm0(i) + ttt1
fm2(i)=fm2(i) + ome*ome*ttt1
suuold=suu(i)
end do
So, after trying to apply most of your inputs and kept not getting to where I want, I finally found a cheat, which is I think acceptable. As everyone else has said, kspect is the problem. Hence, I change the one of the inputs for kspect -->delint
initially, it was 1e-4.. I changed it to 5e-2. it's dropped the processing time by alot obviously but the results are still ok. with this, I think i can run 100,000 number in 5-6hrs approx. which i can still accept.
Please see below, the modified code:
program
implicit none
integer, parameter :: ni = 1
integer, parameter :: nn = 100
integer :: nout ! Number frequency output samples
integer, parameter :: iin = 16 ! input unit
integer, parameter :: iou = 17 ! output unit
integer, parameter :: iou1 = 18 ! output unit 2
integer :: i,j,n,count
real(2), parameter :: pi = 3.141592654358979323846d0
real(2), parameter :: zero = 0.0d0
real(2), parameter :: half = 0.5d0
real(2), parameter :: one = 1.0d0
real(2), parameter :: two = 2.0d0
real(2), parameter :: four = 4.0d0
real(2), parameter :: five = 5.0d0
real(2), parameter :: sixteen = 16.0d0
real(2), parameter :: grav = 9.81
real(2), parameter :: gravsq = 96.2361
real(2), parameter :: twopi = pi*2
real(2) :: siga
real(2) :: sigb
real(2) :: gamma
real(2) :: rho
real(2) :: cdrag
real(2) :: clift
real(2) :: cadd
real(2) :: zcref
real(2) :: vcref
real(2) :: dia
real(2) :: tcoat
real(2) :: tmg
real(2) :: depth
real(2) :: omegamo
real(2) :: delint
real(2) :: cutint
real(2) :: vcur
real(2) :: mumu,stdmu,Pf,sum
real(2) :: muwsub,stdwsub
real(2) :: mutaup,stdtaup
real(2) :: muHs,stdHs
character :: input*20
real(2) :: ome,conalpha
real(2) :: suuold,ttt1
real(2) :: omep,alpha,see(nn),suu(nn),dhyd,Hs(nn)
real(2) :: fh,fv,acc,fi,fd,fl
real(2) :: L,R,us(nn),tu(nn),vel,fm0(nn),fm2(nn),mu(nn),wsub(nn),taup(nn)
REAL TIME1, TIME2
print*,"type the input file with extention"
read (*,*) input
open (unit=iin,file=input)
CALL CPU_TIME(TIME1)
read (iin,*) dia
read (iin,*) tcoat
read (iin,*) tmg
read (iin,*) muwsub,stdwsub
read (iin,*) gamma
read (iin,*) siga
read (iin,*) sigb
read (iin,*) depth
read (iin,*) mutaup,stdtaup
read (iin,*) muHs,stdHs
read (iin,*) omegamo
read (iin,*) nout
read (iin,*) delint
read (iin,*) cutint
read (iin,*) zcref
read (iin,*) vcref
read (iin,*) rho
read (iin,*) cdrag
read (iin,*) cadd
read (iin,*) clift
read (iin,*) mumu,stdmu
read (iin,*) n
call normal(n,mutaup,stdtaup,taup)
call normal(n,muHs,stdHs,Hs)
call normal(n,mumu,stdmu,mu)
call normal(n,muwsub,stdwsub,wsub)
! initialize
conalpha=0.3125d0*(1-0.287*log(gamma))/gravsq
suuold=zero
!
dhyd=dia + two*(tcoat + tmg)
!
vcur=vcref*(((1+0.001/dhyd)*log(1000.*dhyd+1)-1)/log(1000.*zcref+1))
do i=1,n
! omega peak
omep=twopi/taup(i)
! output spectrums
fm0(i)=zero
fm2(i)=zero
j=0
do
j=j + 1
ome=delint*j
call kspect(n,ome,taup,siga,sigb,Hs,conalpha,alpha,gamma,depth,see,suu)
if ((max(see(i), suu(i)).lt.cutint).and.(ome.gt.omep)) exit
ttt1=half*(suuold + suu(i))*delint
fm0(i)=fm0(i) + ttt1
fm2(i)=fm2(i) + ome*ome*ttt1
suuold=suu(i)
end do
!
!
us(i)=two*sqrt(fm0(i))
!
tu(i)=two*pi*sqrt(fm0(i)/fm2(i))
!
vel=us(i)+vcur
!
!
fd=half*rho*cdrag*dhyd*abs(vel)*vel
acc=twopi*us(i)/tu(i)
fi=rho*(one + cadd)*pi*dhyd*dhyd*acc/four
fh=fd + fi
!
fl=half*rho*clift*dhyd*abs(vel)*vel
fv=fl
!
!
R=mu(i)*wsub(i)
L=fh+mu(i)*fv
! monte carlo
if(R-L.le.0)then
count=1
else
count=0
end if
sum=sum+count
end do
Pf=sum/n
CALL CPU_TIME(TIME2)
open (unit=iou,file="output1.txt",action="write",status="replace")
write (iou,*) 'M0 : ',fm0(1)
write (iou,*) 'M2 : ',fm2(1)
write (iou,*) 'Tu : ',tu(1)
write (iou,*) 'U : ',us(1)
write (iou,*) 'V : ',vcur
write (iou,*) 'alpha : ',alpha
write (iou,*) 'Probability ',Pf
write (iou,*) 'Processing time was ', TIME2-TIME1, ' seconds'
close (iou)
print*,'Processing time was ', TIME2-TIME1, ' seconds'
end program
subroutine kspect(n,ome,taup,siga,sigb,Hs,conalpha,alpha,gamma,depth,see,suu)
integer, parameter :: iou = 19 ! output unit
real(2) :: ome
real(2) :: fk
real(2) :: gtran
real(2), parameter :: pi = 3.141592654358979323846d0
real(2), parameter :: zero = 0.0d0
real(2), parameter :: half = 0.5d0
real(2), parameter :: one = 1.0d0
real(2), parameter :: two = 2.0d0
real(2), parameter :: four = 4.0d0
real(2), parameter :: five = 5.0d0
real(2), parameter :: sixteen = 16.0d0
real(2), parameter :: grav = 9.81
real(2), parameter :: gravsq = 96.2361
real(2), parameter :: twopi = pi*2
real(2) :: siga
real(2) :: sigb
real(2) :: depth
real(2) :: gamma
real(2) :: fkbelow,fkabove,fkmid,ttt,sigw,conalpha
integer:: i,j,n
real(2) :: omep,alpha,ee1,ee2,see(n),suu(n),taup(n),Hs(n)
! initialize
sigw=siga
! fk number, use bisection method
fk=zero
if (ome.gt.1.0d-10) then
fkbelow=max(ome*ome/grav, ome/sqrt(grav*depth))
fkabove=two*fkbelow
fkmid=fkbelow
j=1
do
ttt=fkmid - ome*ome/grav/tanh(fkmid*depth)
if (abs(ttt).lt.1.0d-10) exit
if (ttt.gt.zero) then
fkabove=fkmid
else
fkbelow=fkmid
end if
fkmid=half*(fkbelow + fkabove)
j=j + 1
if (j.gt.1000) then
open (unit=iou,file="error.txt",action="write",status="replace")
write(iou,*)'ERROR in dload routine'
write(iou,*)'internal error, failed to converge on wave'
write(iou,*)'number in 1000 iterations'
close (iou)
end if
end do
fk=fkmid
end if
!
ttt=fk*depth
if (ttt.lt.1.0d-6) then
gtran=sqrt(grav/depth)
else if (ttt.lt.150.0d0) then
gtran=ome/sinh(ttt)
else
gtran=zero
end if
do i=1,n
!
omep=twopi/taup(i)
alpha=conalpha*Hs(i)**2*omep**(4)
if (ome.gt.omep) sigw=sigb
if (ome.gt.1d-10) then
ee1=-half*(((ome - omep)/(sigw*omep))**2)
ee2=-five/four*(ome/omep)**(-4)
see(i)=alpha*gravsq*ome**(-5)*exp(ee2)*gamma**exp(ee1)
else
see(i)=zero
end if
!
suu(i)=gtran*gtran*see(i)
end do
return
end subroutine
subroutine normal(n,mu,std,dinvnorm)
!symbols parameters
REAL(KIND=2)::RANDOM@,Prob(n)
real*8:: dinvnorm(n)
real*8:: p_low,p_high
real*8:: a1,a2,a3,a4,a5,a6
real*8:: b1,b2,b3,b4,b5
real*8:: c1,c2,c3,c4,c5,c6
real*8:: d1,d2,d3,d4
real*8:: z,q,r
real*8:: mu,std
integer::n,i
!constant parameters
**********************************************************
input data:
0.4064 !od
0.0213 !tcoat
0.006 !mg
905.4,0 !wsub(mean,std)
3.27 ! gamma
0.068 ! Signma A
0.087 ! Signma B
119 ! depth
7.89,2.19 ! Taup(mean,std)
8.43,2.34 ! Hs (mean,std)
5 !
1000 !
5e-2 ! delint
1e-10 ! cutint
1 ! zcref
1.052 ! vcref
1025 ! density
1.4 ! cd
2.29 ! cm
1.0 ! cl
0.64,0.2 ! mu(mean,std)
100 ! number of samples