Related
This script reads 5 day forecasts from a weather model, and averages a few variables monthly hourly.
Now, I need to get the minimum temperature value.
Example, each day I have 5 days of forecast.
I need an output like this:
January
minimum value of 0h, 1h, 2h, 3h, 4h, etc. It doesn't matter what day it is in January, just the monthly hourly minimum value.
program medias
implicit none
INTEGER,PARAMETER :: NVARS=5
INTEGER :: IM, JM, YEAR2, MONTH2, DAY2, YEAR, MONTH, DAY, LASTYEAR, &
LASTMONTH, LASTDAY, H1, H2, H3, H7, H8, A, B, V, X, Y, TDEF=0
REAL :: LAT, LON, RESX=0.0466611, RESY=0.0448676
INTEGER, DIMENSION(12) :: CALENDAR
CHARACTER(LEN=3), DIMENSION(12) :: MONTHS = (/ 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' /)
CHARACTER(LEN=5), DIMENSION(NVARS) :: VARNAMES = (/ 'PRECI','T2MJU','TD2MJ','U10MJ','V10MJ' /)
REAL, DIMENSION(:,:), ALLOCATABLE :: SURVAR
REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: HOURLY2D, HOURLY2DF, MONTHLY2D, MONTHLY2DF
CHARACTER :: DATE*8, DIROUT*200, DIRRUN*200, FILENAME*200, DYEAR*4, DMONTH*2, DDAY*2, DHOUR*2
! DADOS DE ENTRADA
DIRRUN = '/media/milena/Backup/'
!DIRRUN = '/home/oper/prevtempo/dataout/GrADS_BRAMS-6.5.2/'
DIROUT = '/media/milena/Backup/'
IM = 259
JM = 269
CALENDAR = (/ 31,28,31,30,31,30,31,31,30,31,30,31 /)
H8 = 24
ALLOCATE(SURVAR(IM,JM))
ALLOCATE(HOURLY2DF(IM,JM,H8,5))
ALLOCATE(MONTHLY2DF(IM,JM,12,5))
! Iniciando o armazenamento de dados
TDEF = 0
YEAR = 2022
MONTH = 10
LASTMONTH = 10
LASTYEAR = 2022
H7 = 0
YEAR2 = YEAR
MONTH2 = MONTH
2 H7 = H7+1
H2 = 0
DO WHILE (H2 .LE. 23)
YEAR = YEAR2
MONTH = MONTH2
PRINT*, MONTH
PRINT*, YEAR
H1 = ((LASTYEAR-YEAR)+1)*31*5
ALLOCATE(HOURLY2D(IM,JM,H1,5))
H1 = 0
WRITE (DHOUR,'(BZ,I2.2)') H2
TDEF = TDEF+1
DO WHILE (YEAR .LE. LASTYEAR)
IF (MOD(YEAR,4) .EQ. 0) CALENDAR(2) = 29
LASTDAY = CALENDAR(MONTH)
! IF (MONTH .EQ. LASTMONTH) LASTDAY = 12
DAY = 1
DO WHILE (DAY .LE. LASTDAY)
DAY2 = DAY
A = 8
WRITE (DATE,'(BZ,I4.4,3I2.2)') YEAR,MONTH,DAY
WRITE (DYEAR,'(BZ,I4.4)') YEAR
WRITE (DMONTH,'(BZ,I2.2)') MONTH
IF (H2 .EQ. 0) THEN
DAY2 = DAY2+1
IF ( DAY2 .GT. LASTDAY ) THEN
GO TO 22
END IF
END IF
WRITE (DDAY,'(BZ,I2.2)') DAY2
8 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(8,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
9 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(9,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
10 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(10,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
11 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(11,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
12 FILENAME = TRIM(DIRRUN)//DATE//'00/Go05km-A-'//DYEAR//'-'//DMONTH//'-'//DDAY//'-'//DHOUR//'0000-g1.gra'
OPEN(12,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="read",STATUS="old",RECL=IM*JM*4)
H1 = H1+1
GO TO 21
13 GO TO 22
21 B = 0
DO V =1,175
READ (A,REC=V) SURVAR(:,:)
! Leitura Precipitacao
IF ( V .EQ. 162 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura Tp2m
IF ( V .EQ. 166 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura Td2m
IF ( V .EQ. 167 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura U10m
IF ( V .EQ. 168 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
! Leitura V10m
IF ( V .EQ. 169 ) THEN
B = B+1
HOURLY2D(:,:,H1,B) = SURVAR(:,:)
END IF
END DO
CLOSE(A)
A = A+1
DAY2 = DAY2+1
WRITE (DDAY,'(BZ,I2.2)') DAY2
IF ( DAY2 .GT. LASTDAY ) THEN
GO TO 22
END IF
GO TO (9,10,11,12,13),A-8
22 DAY = DAY+1
END DO
YEAR = YEAR+1
IF (MONTH .GT. LASTMONTH) THEN
GO TO 23
END IF
END DO
23 DO B=1,5
DO Y=1,JM
DO X=1,IM
HOURLY2DF(X,Y,H2,B) = SUM(HOURLY2D(X,Y,1:H1,B))/H1
END DO
END DO
END DO
PRINT*,H2
PRINT*, HOURLY2DF(130,107,H2,1)
PRINT*, HOURLY2DF(130,107,H2,2)
PRINT*, HOURLY2DF(130,107,H2,3)
PRINT*, HOURLY2DF(130,107,H2,4)
PRINT*, HOURLY2DF(130,107,H2,5)
DEALLOCATE(HOURLY2D)
H2 = H2+1
END DO
40 FILENAME = TRIM(DIROUT)//'MEDIA_HORARIA_'//DMONTH//'.bin'
PRINT*, FILENAME
OPEN(40,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="write",STATUS="new",RECL=IM*JM*4)
H3=1
H2=H2-1
DO H2=0,H2
DO B=1,5
WRITE(40,rec=H3) HOURLY2DF(:,:,H2,B)
H3=H3+1
END DO
END DO
CLOSE(40)
DO B=1,5
DO Y=1,JM
DO X=1,IM
MONTHLY2DF(X,Y,H7,B) = SUM(HOURLY2DF(X,Y,0:H2,B))/(H2+1)
END DO
END DO
END DO
PRINT*,'MEDIA MENSAL DO MES ',DMONTH
PRINT*, MONTHLY2DF(153,117,H7,1)
PRINT*, MONTHLY2DF(153,117,H7,2)
PRINT*, MONTHLY2DF(153,117,H7,3)
PRINT*, MONTHLY2DF(153,117,H7,4)
PRINT*, MONTHLY2DF(153,117,H7,5)
MONTH2 = MONTH2+1
IF (MONTH2 .GT. 12) THEN
MONTH2 = 1
YEAR2 = YEAR2+1
END IF
IF (MONTH2 .LE. LASTMONTH) THEN
IF (H7 .LE. 12) THEN
GO TO 2
END IF
END IF
50 FILENAME = TRIM(DIROUT)//'MEDIA_MENSAL_01.bin'
OPEN(50,FILE=TRIM(FILENAME),ACCESS="direct",ACTION="write",STATUS="new",RECL=IM*JM*4)
H3=1
DO H7=1,H7
DO B=1,5
WRITE(50,rec=H3) MONTHLY2DF(:,:,H7,B)
H3=H3+1
END DO
END DO
CLOSE(50)
END PROGRAM medias
I know write statement is just to print the variable. But I have found something in my code.
For example, there are two variables called 'T_avg' and 'T_favg.'
I wanted to print T_favg, I used the line below.
write(*,*) T_favg
result: 100
And then I also wanted to see T_avg, I added variable.
write(*,*) T_avg, T_favg
result: 50, 200
I did not modify the code at all except that line, but the result of T_favg is different.
I used this command line.
ifort.exe /O2 scale_analysis(07022020).f90 -o test.exe
Is there any circumstance occurring it?
**Sorry, I added my code.
PROGRAM scale_analysis
USE, INTRINSIC :: iso_fortran_env, ONLY: real32, real64, FILE_STORAGE_SIZE
IMPLICIT NONE
! DECLARE PARAMETERS
INTEGER, PARAMETER :: SP = real32 ! SINGLE-PRECISION REAL
INTEGER, PARAMETER :: DP = real64 ! DOUBLE-PRECISION REAL
INTEGER, PARAMETER :: nx = 1024 ! TOTAL NUMBER OF GRID POINTS
INTEGER, PARAMETER :: iskip = 2
! DECLARE ALLOCATABLE ARRAYS
REAL(SP), ALLOCATABLE, DIMENSION(:,:,:) :: STMP, T, RHO
! DECLARE VARIABLES FOR SUMMATION
REAL(SP) :: rho_sum, rhoT_sum, T_sum
! DECLARE VARIABLES FOR REYNOLDS-AVERAGING
REAL(SP) :: rho_avg, rhoT_avg, T_avg
! DECLARE VARIABLES FOR FAVRE-AVERAGING
REAL(SP) :: T_favg
INTEGER :: i, j, k
CHARACTER(LEN=100) :: outfile, varname, infile4, infile5
CHARACTER(LEN=100) :: filename
!--------------------------------------------------------------------------
! DEMONSTRATE READ_DATA
!--------------------------------------------------------------------------
ALLOCATE(T(nx/iskip, nx/iskip, nx/iskip))
ALLOCATE(RHO(nx/iskip, nx/iskip, nx/iskip))
ALLOCATE(STMP(nx, nx, nx))
STMP = 0.0_SP
!--------------------------------------------------------------------------
! INITIALIZATION OF SUMMATION VARIABLES
!--------------------------------------------------------------------------
rho_sum = 0.0; rhoT_sum = 0.0;
T_sum = 0.0;
T_avg = 0.0; T_favg = 0.0;
!--------------------------------------------------------------------------
! DATA IMPORT -START
!--------------------------------------------------------------------------
varname = 'Z1_dil_inertHIT'
outfile = 'terms_in_Kolla(Z1_inertHIT).txt'
infile4 = 'E:\AUTOIGNITION\Z1\Temperature_inertHIT.bin'
infile5 = 'E:\AUTOIGNITION\Z1\Density_inertHIT.bin'
OPEN(44, file=TRIM(ADJUSTL(infile4)), status='old', access='stream', &
form='unformatted')
READ(44) stmp
CLOSE(44)
DO k = 1, nx/iskip
DO j = 1, nx/iskip
DO i = 1, nx/iskip
T(i,j,k) = stmp(1+iskip*(i-1), 1+iskip*(j-1), 1+iskip*(k-1))
END DO
END DO
END DO
WRITE(*, '(A)') 'Data4 is successfully read ... '
OPEN(55, file=TRIM(ADJUSTL(infile5)), status='old', access='stream', &
form='unformatted')
READ(55) stmp
CLOSE(55)
DO k = 1, nx/iskip
DO j = 1, nx/iskip
DO i = 1, nx/iskip
RHO(i,j,k) = stmp(1+iskip*(i-1), 1+iskip*(j-1), 1+iskip*(k-1))
END DO
END DO
END DO
WRITE(*, '(A)') 'Data5 is successfully read ... '
DEALLOCATE(stmp)
!--------------------------------------------------------------------------
! COMPUTE U_RMS
!--------------------------------------------------------------------------
DO k = 1, nx/iskip
DO j = 1, nx/iskip
DO i = 1, nx/iskip
rho_sum = rho_sum + RHO(i,j,k)
END DO
END DO
END DO
rho_avg = rho_sum / REAL((nx/iskip)**3)
!--------------------------------------------------------------------------
! COMPUTE TEMPERATRUE TAYLOR LENGTH SCALE(LAMBDA_T)
! C.TOWERY, DETONATION INITIATION BY COMPRESSIBLE TURBULENCE THERMODYNAMIC
! FLUCTUATIONS, CNF, 2019
!--------------------------------------------------------------------------
DO k = 1, nx/iskip
DO j = 1, nx/iskip
DO i = 1, nx/iskip
T_sum = T_sum + T(i,j,k)
rhoT_sum = rhoT_sum + ( RHO(i,j,k)*T(i,j,k) )
END DO
END DO
END DO
T_avg = T_sum / REAL((nx/iskip)**3)
rhoT_avg = rhoT_sum / REAL((nx/iskip)**3)
T_favg = rhoT_avg / rho_avg
DO k = 1, nx/iskip
DO j = 1, nx/iskip
DO i = 1, nx/iskip
rhoT_p_sum = rhoT_p_sum + RHO(i,j,k)*( (T(i,j,k) - T_favg)**2 )
END DO
END DO
END DO
rhoT_p_avg = rhoT_p_sum / REAL((nx/iskip)**3)
T_p = SQRT( rhoT_p_avg / rho_avg )
write(*,*) T_favg
write(*,*) T_avg,T_favg
END PROGRAM scale_analysis
The problematic part is write statement. If I erase T_avg from the second write statement line, then T_favg changes.
I have a fortran code that computes the solution vector using the thomas algorithm subroutine.
I want the solution vector to run in a loop for a certain number of time.
How do i call this subroutine in the loop?
my subroutine is the thomas algorithm subroutine.
It returns the solution vector u but I want it to use the vectors NN times in a loop. So the old u becomes the new u to use in the subroutine.
How do I do this?
Below is the what i tried
program thomasalg2
implicit double precision(A-H,O-Z)
real*8, dimension(9,1) :: a,b,c,r,u,uold!the dimension is subject to change depending on the size of the new matrix
!real*8, dimension(9,50) :: W
real*8 :: pi
real*8 :: h,k,lm,l,T
integer :: i,j,al,NN,n
l = 1!right endpoint on the X-axis
n = 9 !number of rols/cols of the coefficient matrix with boundaries included
T = 0.5 !maximum number of the time variable
NN = 50!number of time steps
np = n
h = l/n
k = T/NN
al = 1.0D0 !alpha
pi = dacos(-1.0D0)
lm = (al**2)*(k/(h**2)) !lambda
do i = 1,n
r(i,1) = sin(pi*i*h) !this is W_0
end do
a(1,1) = 0.0D0
do i = 2,n
a(i,1) = -lm
end do
do i = 1,n
b(i,1) = 1 + (2*lm)
end do
c(9,1) = 0.0D0
do i = 1,n-1
c(i,1) = -lm
end do
!the 3 diagonals are stored in the 1st, 2nd, 3rd & 4th files respectively.
open(10, file = 'thom1.txt')
open(11, file = 'thom2.txt')
open(12, file = 'thom3.txt')
open(13, file = 'thom4.txt')
write(10,*)
do i = 1,n
write(10,*) a(i,1)
end do
write(11,*)
do i = 1,n
write(11,*) b(i,1)
end do
write(12,*)
do i = 1,n
write(12,*) c(i,1)
end do
write(13,*)
do i = 1,n
write(13,*) r(i,1)
end do
open(14, file = 'tridag2.txt')
write(14,*)
n = 9
do i = 1,n
write(14,*) a(i,1),b(i,1),c(i,1),r(i,1) !write the given vectors in the file in the form of a column vector
end do
call tridag(a,b,c,r,u,n)
!solve the given system and return the solution vector u
do i = 1,NN
call tridag(a,b,c,r,u,n)
!write(15,*) u
r = u
end do
open(15, file = 'tridag2u.txt')
write(15,*)
!write the solution vector in the form of a column vector
do i = 1,n
write(15,*) u(i,1)
end do
!print *, "Your data has been written in 'tridag2.txt'"
end program thomasalg2
subroutine tridag(a,b,c,r,u,n)
implicit double precision (A-H, O-Z)
integer n, NMAX
real*8 a(n), b(n), c(n), r(n), u(n)
parameter (NMAX = 500)
integer j
real*8 bet, gam(NMAX)
if(b(1).eq.0.) stop "tridag: rewrite equations"
bet = b(1)
u(1)=r(1)/bet
do j = 2,n
gam(j) = c(j-1)/bet
bet = b(j)-a(j)*gam(j)
if (bet.eq.0.) stop "tridag failed"
u(j) = (r(j)-a(j)*u(j-1))/bet
end do
do j = n-1,1,-1
u(j) = u(j)-gam(j+1)*u(j+1)
end do
!print *, "The solution is", u
return
end subroutine
I am doing a multiple integral, there is a parameter M_D which I can modify. Both M_D=2.9d3 or M_D=3.1d3 works fine, but when I change it into M_D=3.0d0 it got an error
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F831A103E08
#1 0x7F831A102F90
#2 0x7F83198344AF
#3 0x43587C in __mc_vegas_MOD_vegas
#4 0x400EBE in MAIN__ at MAINqq.f90:?
Segmentation fault (core dumped)
It's very unlikely there is a sigularity which out of range while progressing. From the answer to this kind of problem I found, I guess it's not about array dimension that is out of bounds.
This time I didn't make it to simplify the problem which can demonstrate my question in order to write less amount of code . It's unpractical to post all the code here, so I post the segment which I think is relevant to the error.
module my_fxn
implicit none
private
public :: fxn_1
public :: cos_theta
real(kind(0d0)), parameter :: S=1.690d8
real(kind(0d0)), parameter :: g_s = 0.118d0
real(kind(0d0)), parameter :: M_D = 3.0d3 !!!
real(kind(0d0)), parameter :: m=172d0
real(kind(0d0)), parameter :: Q=2d0
real(kind(0d0)), parameter :: pi=3.14159d0
real(kind(0d0)), external :: CT14pdf
real(kind(0d0)) :: cos_theta
real(kind(0d0)) :: s12
integer :: i
contains
function jacobian( upper, lower) result(jfactor)
implicit none
real(kind(0d0)), dimension(1:6) :: upper, lower
real(kind(0d0)) :: jfactor
jfactor = 1d0
do i = 1, 6
jfactor = jfactor * (upper(i) - lower(i))
end do
end function jacobian
function dot_vec(p,q) result(fourvectordot)
implicit none
real(kind(0d0)) :: fourvectordot
real(kind(0d0)), dimension(0:3) :: p,q
fourvectordot = p(0) * q(0)
do i = 1, 3
fourvectordot = fourvectordot - p(i) * q(i)
end do
end function dot_vec
subroutine commonpart(p3_0, p4_0, eta, k_v,P3_v, p4_v, s13, s14, s23, s24)
implicit none
real(kind(0d0)), intent(in) :: p3_0, p4_0, eta, k_v, p3_v, p4_v
real(kind(0d0)), intent(out):: s13, s14, s23, s24
real(kind(0d0)) :: sin_theta, &
cos_eta, sin_eta, &
cos_ksi, sin_ksi
real(kind(0d0)), dimension(0:3) :: k1, k2, p3, p4, k
sin_theta = sqrt(1-cos_theta**2)
cos_eta = cos(eta)
sin_eta = sqrt(1-cos_eta**2)
cos_ksi = (k_v**2-p3_v**2-p4_v**2)/(2*p3_v*p4_v)
sin_ksi = sqrt(1-cos_ksi**2)
k1 = [sqrt(s12)/2d0,0d0,0d0, sqrt(s12)/2d0]
k2 = [sqrt(s12)/2d0,0d0,0d0, -sqrt(s12)/2d0]
p3 = [p3_0, p3_v*(cos_theta*cos_eta*sin_ksi+sin_theta*cos_ksi), &
p3_v* sin_eta*sin_ksi, p3_v*( cos_theta*cos_ksi-sin_theta*cos_eta*sin_ksi)]
p4 = [p4_0, p4_v*sin_theta, 0d0, p4_v*cos_theta]
do i = 1, 3
k(i) = 0 - p3(i) - p4(i)
end do
k(0) = sqrt(s12) - p3_0-p4_0
s13 = m**2- 2*dot_vec(k1,p3)
s14 = m**2- 2*dot_vec(k1,p4)
s23 = m**2- 2*dot_vec(k2,p3)
s24 = m**2- 2*dot_vec(k2,p3)
end subroutine commonpart
function fxn_1(z, wgt) result(fxn_qq)
implicit none
real(kind(0d0)), dimension(1:6) :: z
real(kind(0d0)) :: wgt
real(kind(0d0)) :: tau_0
real(kind(0d0)) :: sigma, tau, m_plus, m_minus, & ! intermediate var
p3_v, p4_v, k_v, phi
real(kind(0d0)) :: s13,s14,s23, s24, gm
real(kind(0d0)) :: part1_qq,part_qq,fxn_qq
real(kind(0d0)) :: p3_0_max, p4_0_max, eta_max, gm_max, x1_max, x2_max, &
p3_0_min, p4_0_min, eta_min, gm_min, x1_min, x2_min
real(kind(0d0)), dimension(1:6) :: upper, lower
real(kind(0d0)) :: jfactor
wgt = 0
gm_max = M_D
gm_min = 0.1d0
z(1)= (gm_max-gm_min)*z(1) + gm_min
tau_0 = (2*m)**2/S
eta_max = 2*pi
eta_min = 0
z(2) = (eta_max-eta_min)*z(2)+eta_min
x1_max = 1
x1_min = tau_0
z(3) = (x1_max-x1_min)*z(3) + x1_min
x2_max = 1
x2_min = tau_0/z(3)
z(4) = (x2_max-x2_min)*z(4)+x2_min
s12 = z(3)*z(4) * S
if (sqrt(s12) < (2*m+z(1)))then
fxn_qq = 0d0
return
else
end if
p4_0_max = sqrt(s12)/2 - ((m+z(1))**2-m**2)/(2*sqrt(s12))
p4_0_min = m
z(5) = (p4_0_max-p4_0_min)*z(5)+p4_0_min
p4_v = sqrt(z(5)**2-m**2)
sigma = sqrt(s12)-z(5)
tau = sigma**2 - p4_v**2
m_plus = m + z(1)
m_minus = m - z(1)
p3_0_max = 1/(2*tau)*(sigma*(tau+m_plus*m_minus)+p4_v*sqrt((tau-m_plus**2)*(tau-m_minus**2)))
p3_0_min = 1/(2*tau)*(sigma*(tau+m_plus*m_minus)-p4_v-sqrt((tau-m_plus**2)*(tau-m_minus**2)))
z(6) = (p3_0_max-p3_0_min)*z(6)+p3_0_min
p3_v = sqrt(z(6)**2-m**2)
k_v = sqrt((sqrt(s12)-z(5)-z(6))**2-z(1)**2)
gm = z(1)
upper = [gm_max, eta_max, x1_max, x2_max, p4_0_max, p3_0_max]
lower = [gm_min, eta_min, x1_min, x2_min, p4_0_min, p3_0_min]
jfactor = jacobian(upper, lower)
call commonpart(z(6),z(5),z(2), k_v,p3_v, p4_v, s13, s14, s23, s24)
include "juicy.m"
part1_qq = 0d0
do i = 1, 5
part1_qq = part1_qq+CT14Pdf(i, z(3), Q)*CT14Pdf(-i, z(4), Q)*part_qq
end do
phi = 1/(8*(2*pi)**4) * 1/(2*s12)
fxn_qq = jfactor * g_s**4/M_D**5*pi*z(1)**2*phi*part1_qq
end function fxn_1
end module my_fxn
MC_VEGAS
MODULE MC_VEGAS
!*****************************************************************
! This module is a modification f95 version of VEGA_ALPHA.for
! by G.P. LEPAGE SEPT 1976/(REV)AUG 1979.
!*****************************************************************
IMPLICIT NONE
SAVE
INTEGER,PARAMETER :: MAX_SIZE=20 ! The max dimensions of the integrals
INTEGER,PRIVATE :: i_vegas
REAL(KIND(1d0)),DIMENSION(MAX_SIZE),PUBLIC:: XL=(/(0d0,i_vegas=1,MAX_SIZE)/),&
XU=(/(1d0,i_vegas=1,MAX_SIZE)/)
INTEGER,PUBLIC :: NCALL=50000,& ! The number of integrand evaluations per iteration
!+++++++++++++++++++++++++++++++++++++++++++++++++++++
! You can change NCALL to change the precision
!+++++++++++++++++++++++++++++++++++++++++++++++++++++
ITMX=5,& ! The maximum number of iterations
NPRN=5,& ! printed or not
NDEV=6,& ! device number for output
IT=0,& ! number of iterations completed
NDO=1,& ! number of subdivisions on an axis
NDMX=50,& ! determines the maximum number of increments along each axis
MDS=1 ! =0 use importance sampling only
! =\0 use importance sampling and stratified sampling
! increments are concentrated either wehre the
! integrand is largest in magnitude (MDS=1), or
! where the contribution to the error is largest(MDS=-1)
INTEGER,PUBLIC :: IINIP
REAL(KIND(1d0)),PUBLIC :: ACC=-1d0 ! Algorithm stops when the relative accuracy,
! |SD/AVGI|, is less than ACC; accuracy is not
! cheched when ACC<0
REAL(KIND(1d0)),PUBLIC :: MC_SI=0d0,& ! sum(AVGI_i/SD_i^2,i=1,IT)
SWGT=0d0,& ! sum(1/SD_i^2,i=1,IT)
SCHI=0d0,& ! sum(AVGI_i^2/SD_i^2,i=1,IT)
ALPH=1.5d0 ! controls the rate which the grid is modified from
! iteration to iteration; decreasing ALPH slows
! modification of the grid
! (ALPH=0 implies no modification)
REAL(KIND(1d0)),PUBLIC :: DSEED=1234567d0 ! seed of
! location of the I-th division on the J-th axi, normalized to lie between 0 and 1.
REAL(KIND(1d0)),DIMENSION(50,MAX_SIZE),PUBLIC::XI=1d0
REAL(KIND(1d0)),PUBLIC :: CALLS,TI,TSI
CONTAINS
SUBROUTINE RANDA(NR,R)
IMPLICIT NONE
INTEGER,INTENT(IN) :: NR
REAL(KIND(1d0)),DIMENSION(NR),INTENT(OUT) :: R
INTEGER :: I
! D2P31M=(2**31) - 1 D2P31 =(2**31)(OR AN ADJUSTED VALUE)
REAL(KIND(1d0))::D2P31M=2147483647.d0,D2P31=2147483711.d0
!FIRST EXECUTABLE STATEMENT
DO I=1,NR
DSEED = DMOD(16807.d0*DSEED,D2P31M)
R(I) = DSEED / D2P31
ENDDO
END SUBROUTINE RANDA
SUBROUTINE VEGAS(NDIM,FXN,AVGI,SD,CHI2A,INIT)
!***************************************************************
! SUBROUTINE PERFORMS NDIM-DIMENSIONAL MONTE CARLO INTEG'N
! - BY G.P. LEPAGE SEPT 1976/(REV)AUG 1979
! - ALGORITHM DESCRIBED IN J COMP PHYS 27,192(1978)
!***************************************************************
! Without INIT or INIT=0, CALL VEGAS
! INIT=1 CALL VEGAS1
! INIT=2 CALL VEGAS2
! INIT=3 CALL VEGAS3
!***************************************************************
IMPLICIT NONE
INTEGER,INTENT(IN) :: NDIM
REAL(KIND(1d0)),EXTERNAL :: FXN
INTEGER,INTENT(IN),OPTIONAL :: INIT
REAL(KIND(1d0)),INTENT(INOUT) :: AVGI,SD,CHI2A
REAL(KIND(1d0)),DIMENSION(50,MAX_SIZE):: D,DI
REAL(KIND(1d0)),DIMENSION(50) :: XIN,R
REAL(KIND(1d0)),DIMENSION(MAX_SIZE) :: DX,X,DT,RAND
INTEGER,DIMENSION(MAX_SIZE) :: IA,KG
INTEGER :: initflag
REAL(KIND(1d0)),PARAMETER :: ONE=1.d0
INTEGER :: I, J, K, NPG, NG, ND, NDM, LABEL = 0
REAL(KIND(1d0)) :: DXG, DV2G, XND, XJAC, RC, XN, DR, XO, TI2, WGT, FB, F2B, F, F2
!***************************
!SAVE AVGI,SD,CHI2A
!SQRT(A)=DSQRT(A)
!ALOG(A)=DLOG(A)
!ABS(A)=DABS(A)
!***************************
IF(PRESENT(INIT))THEN
initflag=INIT
ELSE
initflag=0
ENDIF
! INIT=0 - INITIALIZES CUMULATIVE VARIABLES AND GRID
ini0:IF(initflag.LT.1) THEN
NDO=1
DO J=1,NDIM
XI(1,J)=ONE
ENDDO
ENDIF ini0
! INIT=1 - INITIALIZES CUMULATIVE VARIABLES, BUT NOT GRID
ini1:IF(initflag.LT.2) THEN
IT=0
MC_SI=0.d0
SWGT=MC_SI
SCHI=MC_SI
ENDIF ini1
! INIT=2 - NO INITIALIZATION
ini2:IF(initflag.LE.2)THEN
ND=NDMX
NG=1
IF(MDS.NE.0) THEN
NG=(NCALL/2.d0)**(1.d0/NDIM)
MDS=1
IF((2*NG-NDMX).GE.0) THEN
MDS=-1
NPG=NG/NDMX+1
ND=NG/NPG
NG=NPG*ND
ENDIF
ENDIF
K=NG**NDIM ! K sub volumes
NPG=NCALL/K ! The number of random numbers in per sub volumes Ms
IF(NPG.LT.2) NPG=2
CALLS=DBLE(NPG*K) ! The total number of random numbers M
DXG=ONE/NG
DV2G=(CALLS*DXG**NDIM)**2/NPG/NPG/(NPG-ONE) ! 1/(Ms-1)
XND=ND ! ~NDMX!
! determines the number of increments along each axis
NDM=ND-1 ! ~NDMX-1
DXG=DXG*XND ! determines the number of increments along each axis per sub-v
XJAC=ONE/CALLS
DO J=1,NDIM
DX(J)=XU(J)-XL(J)
XJAC=XJAC*DX(J) ! XJAC=Volume/M
ENDDO
! REBIN, PRESERVING BIN DENSITY
IF(ND.NE.NDO) THEN
RC=NDO/XND ! XND=ND
outer:DO J=1, NDIM ! Set the new division
K=0
XN=0.d0
DR=XN
I=K
LABEL=0
inner5:DO
IF(LABEL.EQ.0) THEN
inner4:DO
K=K+1
DR=DR+ONE
XO=XN
XN=XI(K,J)
IF(RC.LE.DR) EXIT
ENDDO inner4
ENDIF
I=I+1
DR=DR-RC
XIN(I)=XN-(XN-XO)*DR
IF(I.GE.NDM) THEN
EXIT
ELSEIF(RC.LE.DR) THEN
LABEL=1
ELSE
LABEL=0
ENDIF
ENDDO inner5
inner:DO I=1,NDM
XI(I,J)=XIN(I)
ENDDO inner
XI(ND,J)=ONE
ENDDO outer
NDO=ND
ENDIF
IF(NPRN.GE.0) WRITE(NDEV,200) NDIM,CALLS,IT,ITMX,ACC,NPRN,&
ALPH,MDS,ND,(XL(J),XU(J),J=1,NDIM)
ENDIF ini2
!ENTRY VEGAS3(NDIM,FXN,AVGI,SD,CHI2A) INIT=3 - MAIN INTEGRATION LOOP
mainloop:DO
IT=IT+1
TI=0.d0
TSI=TI
DO J=1,NDIM
KG(J)=1
DO I=1,ND
D(I,J)=TI
DI(I,J)=TI
ENDDO
ENDDO
LABEL=0
level1:DO
level2:DO
ifla:IF(LABEL.EQ.0)THEN
FB=0.d0
F2B=FB
level3:DO K=1,NPG
CALL RANDA(NDIM,RAND)
WGT=XJAC
DO J=1,NDIM
XN=(KG(J)-RAND(J))*DXG+ONE
IA(J)=XN
IF(IA(J).LE.1) THEN
XO=XI(IA(J),J)
RC=(XN-IA(J))*XO
ELSE
XO=XI(IA(J),J)-XI(IA(J)-1,J)
RC=XI(IA(J)-1,J)+(XN-IA(J))*XO
ENDIF
X(J)=XL(J)+RC*DX(J)
WGT=WGT*XO*XND
ENDDO
F=WGT
F=F*FXN(X,WGT)
F2=F*F
FB=FB+F
F2B=F2B+F2
DO J=1,NDIM
DI(IA(J),J)=DI(IA(J),J)+F
IF(MDS.GE.0) D(IA(J),J)=D(IA(J),J)+F2
ENDDO
ENDDO level3
! K=K-1 !K=NPG
F2B=DSQRT(F2B*DBLE(NPG))
F2B=(F2B-FB)*(F2B+FB)
TI=TI+FB
TSI=TSI+F2B
IF(MDS.LT.0) THEN
DO J=1,NDIM
D(IA(J),J)=D(IA(J),J)+F2B
ENDDO
ENDIF
K=NDIM
ENDIF ifla
KG(K)=MOD(KG(K),NG)+1
IF(KG(K).EQ.1) THEN
EXIT
ELSE
LABEL=0
ENDIF
ENDDO level2
K=K-1
IF(K.GT.0) THEN
LABEL=1
ELSE
EXIT
ENDIF
ENDDO level1
! COMPUTE FINAL RESULTS FOR THIS ITERATION
TSI=TSI*DV2G
TI2=TI*TI
WGT=ONE/TSI
MC_SI=MC_SI+TI*WGT
SWGT=SWGT+WGT
SCHI=SCHI+TI2*WGT
AVGI=MC_SI/SWGT
CHI2A=(SCHI-MC_SI*AVGI)/(IT-0.9999d0)
SD=DSQRT(ONE/SWGT)
IF(NPRN.GE.0) THEN
TSI=DSQRT(TSI)
WRITE(NDEV,201) IT,TI,TSI,AVGI,SD,CHI2A
ENDIF
IF(NPRN.GT.0) THEN
DO J=1,NDIM
WRITE(NDEV,202) J,(XI(I,J),DI(I,J),I=1+NPRN/2,ND,NPRN)
ENDDO
ENDIF
!*************************************************************************************
! REFINE GRID
! XI(k,j)=XI(k,j)-(XI(k,j)-XI(k-1,j))*(sum(R(i),i=1,k)-s*sum(R(i),i=1,ND)/M)/R(k)
! divides the original k-th interval into s parts
!*************************************************************************************
outer2:DO J=1,NDIM
XO=D(1,J)
XN=D(2,J)
D(1,J)=(XO+XN)/2.d0
DT(J)=D(1,J)
inner2:DO I=2,NDM
D(I,J)=XO+XN
XO=XN
XN=D(I+1,J)
D(I,J)=(D(I,J)+XN)/3.d0
DT(J)=DT(J)+D(I,J)
ENDDO inner2
D(ND,J)=(XN+XO)/2.d0
DT(J)=DT(J)+D(ND,J)
ENDDO outer2
le1:DO J=1,NDIM
RC=0.d0
DO I=1,ND
R(I)=0.d0
IF(D(I,J).GT.0.) THEN
XO=DT(J)/D(I,J)
R(I)=((XO-ONE)/XO/DLOG(XO))**ALPH
ENDIF
RC=RC+R(I)
ENDDO
RC=RC/XND
K=0
XN=0.d0
DR=XN
I=K
LABEL=0
le2:DO
le3:DO
IF(LABEL.EQ.0)THEN
K=K+1
DR=DR+R(K)
XO=XN
XN=XI(K,J)
ENDIF
IF(RC.LE.DR) THEN
EXIT
ELSE
LABEL=0
ENDIF
ENDDO le3
I=I+1
DR=DR-RC
XIN(I)=XN-(XN-XO)*DR/R(K)
IF(I.GE.NDM) THEN
EXIT
ELSE
LABEL=1
ENDIF
ENDDO le2
DO I=1,NDM
XI(I,J)=XIN(I)
ENDDO
XI(ND,J)=ONE
ENDDO le1
IF(IT.GE.ITMX.OR.ACC*ABS(AVGI).GE.SD) EXIT
ENDDO mainloop
200 FORMAT(/," INPUT PARAMETERS FOR MC_VEGAS: ",/," NDIM=",I3," NCALL=",F8.0,&
" IT=",I3,/," ITMX=",I3," ACC= ",G9.3,&
" NPRN=",I3,/," ALPH=",F5.2," MDS=",I3," ND=",I4,/,&
"(XL,XU)=",(T10,"(" G12.6,",",G12.6 ")"))
201 FORMAT(/," INTEGRATION BY MC_VEGAS ", " ITERATION NO. ",I3, /,&
" INTEGRAL = ",G14.8, /," SQURE DEV = ",G10.4,/,&
" ACCUMULATED RESULTS: INTEGRAL = ",G14.8,/,&
" DEV = ",G10.4, /," CHI**2 PER IT'N = ",G10.4)
! X is the division of the coordinate
! DELTA I is the sum of F in this interval
202 FORMAT(/,"DATA FOR AXIS ",I2,/," X DELTA I ", &
24H X DELTA I ,18H X DELTA I, &
/(1H ,F7.6,1X,G11.4,5X,F7.6,1X,G11.4,5X,F7.6,1X,G11.4))
END SUBROUTINE VEGAS
END MODULE MC_VEGAS
Main.f90
program main
use my_fxn
use MC_VEGAS
implicit none
integer, parameter :: NDIM = 6
real(kind(0d0)) :: avgi, sd, chi2a
Character(len=40) :: Tablefile
data Tablefile/'CT14LL.pds'/
Call SetCT14(Tablefile)
call vegas(NDIM,fxn_1,avgi,sd,chi2a)
print *, avgi
end program main
After running build.sh
#!/bin/sh
rm -rf *.mod
rm -rf *.o
rm -rf ./calc
rm DATAqq.txt
gfortran -c CT14Pdf.for
gfortran -c FXNqq.f90
gfortran -c MC_VEGAS.f90
gfortran -c MAINqq.f90
gfortran -g -fbacktrace -fcheck=all -Wall -o calc MAINqq.o CT14Pdf.o FXNqq.o MC_VEGAS.o
./calc
rm -rf *.mod
rm -rf *.o
rm -rf ./calc
The whole output has not changed
rm: cannot remove 'DATAqq.txt': No such file or directory
INPUT PARAMETERS FOR MC_VEGAS:
NDIM= 6 NCALL= 46875. IT= 0
ITMX= 5 ACC= -1.00 NPRN= 5
ALPH= 1.50 MDS= 1 ND= 50
(XL,XU)= ( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
INTEGRATION BY MC_VEGAS ITERATION NO. 1
INTEGRAL = NaN
SQURE DEV = NaN
ACCUMULATED RESULTS: INTEGRAL = NaN
DEV = NaN
CHI**2 PER IT'N = NaN
DATA FOR AXIS 1
X DELTA I X DELTA I X DELTA I
.060000 0.2431E-14 .160000 0.5475E-15 .260000 0.8216E-14
.360000 0.3641E-14 .460000 0.6229E-12 .560000 0.6692E-13
.660000 0.9681E-15 .760000 0.9121E-15 .860000 0.2753E-13
.960000 -0.9269E-16
DATA FOR AXIS 2
X DELTA I X DELTA I X DELTA I
.060000 0.1658E-13 .160000 0.5011E-14 .260000 0.8006E-12
.360000 0.1135E-14 .460000 0.9218E-13 .560000 0.7337E-15
.660000 0.6192E-12 .760000 0.3676E-14 .860000 0.2315E-14
.960000 0.5426E-13
DATA FOR AXIS 3
X DELTA I X DELTA I X DELTA I
.060000 0.3197E-14 .160000 0.1096E-12 .260000 0.5996E-14
.360000 0.5695E-13 .460000 0.3240E-14 .560000 0.5504E-13
.660000 0.9276E-15 .760000 0.6193E-12 .860000 0.1151E-13
.960000 0.7968E-17
DATA FOR AXIS 4
X DELTA I X DELTA I X DELTA I
.060000 0.3605E-13 .160000 0.1656E-14 .260000 0.7266E-12
.360000 0.2149E-13 .460000 0.8086E-13 .560000 0.9119E-14
.660000 0.3692E-15 .760000 0.6499E-15 .860000 0.1906E-17
.960000 0.1542E-19
DATA FOR AXIS 5
X DELTA I X DELTA I X DELTA I
.060000 -0.4229E-15 .160000 -0.4056E-14 .260000 -0.1121E-14
.360000 0.6757E-15 .460000 0.7460E-14 .560000 0.9331E-15
.660000 0.8301E-14 .760000 0.6595E-14 .860000 -0.5203E-11
.960000 0.6361E-12
DATA FOR AXIS 6
X DELTA I X DELTA I X DELTA I
.060000 0.2111E-12 .160000 0.5410E-13 .260000 0.1418E-12
.360000 0.1103E-13 .460000 0.8338E-14 .560000 -0.5840E-14
.660000 0.1263E-14 .760000 -0.1501E-15 .860000 0.4647E-14
.960000 0.3134E-15
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F9D828B0E08
#1 0x7F9D828AFF90
#2 0x7F9D81FE24AF
#3 0x43586C in __mc_vegas_MOD_vegas
#4 0x400EAE in MAIN__ at MAINqq.f90:?
Segmentation fault (core dumped)
I am performing an SVD of a matrix using the LAPACK library and then multiplying the matrices to double check that they are correct. See the code below
subroutine svd_and_dgemm() ! -- Matrix decomp: A = USV^t
implicit none
integer,parameter :: m = 2
integer,parameter :: n = 3
integer i,info,lda,ldu,ldv,lwork,l,lds,ldc,ldvt,ldd
real*8 :: a(m,n),a_copy(m,n),sdiag(min(m,n)),s(m,n),u(m,m),vt(n,n),alpha,beta,c(m,n),d(m,n)
character jobu, jobv, transu, transs
real*8, allocatable, dimension ( : ) :: work
lwork = max(1,3*min(m,n) + max(m,n), 5*min(m,n))
allocate (work(lwork))
a = reshape((/3,1,1,-1,3,1/),shape(a),order=(/2, 1/)) !column-wise
print*,'A'
print*, a(1,1), a(1,2), a(1,3)
print*, a(2,1), a(2,2), a(2,3)
jobu = 'A'
jobv = 'A'
lda = m
ldu = m
ldv = n
a_copy = a
call dgesvd (jobu, jobv, m, n, a_copy, lda, sdiag, u, ldu, vt, ldv, work, lwork, info)
if ( info /= 0 ) then
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'R8MAT_SVD_LAPACK - Failure!'
write ( *, '(a)' ) ' The SVD could not be calculated.'
write ( *, '(a)' ) ' LAPACK routine DGESVD returned a nonzero'
write ( *, '(a,i8)' ) ' value of the error flag, INFO = ', info
return
end if
!
! Make the MxN matrix S from the diagonal values in SDIAG.
s(1:m,1:n) = 0.0D+00
do i = 1, min ( m, n )
s(i,i) = sdiag(i)
end do
print*,'U'
print*, u(1,1), u(1,2)
print*, u(2,1), u(2,2)
print*,'S'
print*, s(1,1), s(1,2), s(1,3)
print*, s(2,1), s(2,2), s(2,3)
print*,'Vt'
print*, vt(1,1), vt(1,2), vt(1,3)
print*, vt(2,1), vt(2,2), vt(2,3)
print*, vt(3,1), vt(3,2), vt(3,3)
deallocate (work)
! -- Verify SVD: A = USV^t
! -- Compute C = US
transu = 'N'
transs = 'N'
ldu = m; lds = m; ldc = m
alpha = 1.; beta = 1.
call dgemm(transu,transs,m,n,m,alpha,u,ldu,s,lds,beta,c,ldc)
! -- Compute A = D = CV^t
l = m ! nrows C
ldvt = n; ldd = m
call dgemm(transu,transs,m,n,n,alpha,c,ldc,vt,ldvt,beta,d,ldd)
print*,'C'
print*, c(1,1), c(1,2), c(1,3)
print*, c(2,1), c(2,2), c(2,3)
print*,'D'
print*, d(1,1), d(1,2), d(1,3)
print*, d(2,1), d(2,2), d(2,3)
end subroutine svd_and_dgemm
The output I get is
A
3.0000000000000000 1.0000000000000000 1.0000000000000000
-1.0000000000000000 3.0000000000000000 1.0000000000000000
U
-0.70710678118654835 -0.70710678118654657
-0.70710678118654668 0.70710678118654846
S
3.4641016151377553 0.0000000000000000 0.0000000000000000
0.0000000000000000 3.1622776601683795 0.0000000000000000
Vt
-0.40824829046386402 -0.81649658092772526 -0.40824829046386291
-0.89442719099991508 0.44721359549995882 5.2735593669694936E-016
-0.18257418583505536 -0.36514837167011066 0.91287092917527679
C
-2.4494897427831814 -2.2360679774997867 0.0000000000000000
-2.4494897427831757 2.2360679774997929 0.0000000000000000
D
2.9999999999999991 1.0000000000000002 0.99999999999999989
NaN 2.9999999999999991 1.0000000000000000
So I am not sure where is this NaN coming from. The odd thing is that if before printing D in such way I print it as follows:
print*,'D'
print*, d
Then I don't get the NaN anymore, so the output for D is
D
2.9999999999999991 -0.99999999999999933 1.0000000000000002 2.9999999999999991 0.99999999999999989 1.0000000000000000
D
2.9999999999999991 1.0000000000000002 0.99999999999999989
-0.99999999999999933 2.9999999999999991 1.0000000000000000
Any idea why is this happening?
PS: Information for the dgesvd (LAPACK) and dgemm (BLAS) subroutines.
So from our comments dialogue it seems like you have a problem that stems from not initializing an array. It is always good practice to do this, and in situations where you do operations like var = var +1 it is required. If you are unlucky your program will work fine anyway. But then strange things happen once in a while when some garbage happened to reside in memory where the array gets allocated.
A double should be initialized like this
array = 0.0d0 ! for double precision
or
array = 0 ! ok for single,double and integer
Initialize single precision but not double precision like this:
array = 0.0 ! single (not double) precision.
or this
array = 0.0e0 ! single (not double) precision.
I recommend the page fortran90.org.