Fortran rank mismatch error - fortran
I receive the following error
Compiling file: tropic.f
Warning: Extension: Tab character in format at (1)
C:\Users\Marchant\Desktop\tropic.f(432) : error - Expected a right parenthesis in expression at column 72
Warning: Rank mismatch in argument 'tk' at (1) (scalar and rank-1)
Warning: Rank mismatch in argument 't' at (1) (scalar and rank-1)
Warning: Rank mismatch in argument 'tk' at (1) (scalar and rank-1)
Warning: Rank mismatch in argument 't' at (1) (scalar and rank-1)
Compilation failed.
in this program,
dimension ts1(3),ts2(3),ta1(3),ta2(3),out(14,300)
real lwc, lambda
common /params/xkap,pr,tr,xl,cp,rgas,grav,taue,taus,taup,tauc
common /param2/ pbot,ptop,dp,gam, bt,ct,tao,a21,lambda,lwc
common /heat/ beta,olr1,olr2,alb0,albgr,expo1,expo2,alb1,alb2
pbot=1.0e5
ptop=2.0e4
dp=pbot-ptop
open(12,file='tropic.in',form='formatted')
read(12,*) itermx, delt, iprint
read(12,*) lambda, gam, bt, ct, a1
read(12,*) beta,olr1,olr2,alb0,albgr,expo1,expo2
write(*,*) 'olr1=',olr1,', olr2=',olr2,', expo1=',expo1,', expo2='
1 ,expo2
c ** Set relative areas of convecting a1 and nonconvecting a2 regions.
c a1=.3
tao=265.
alpha=0.06
alpha2=alpha/2.
alpha1=1.-alpha
c expo1=80.
c expo2=80.
expa1=0.
expa2=0.
co=4.2e7
ca=1.0e7
xkap=0.288
rvap=461.
cp=1004.
rgas=287.
grav=9.81
c gam=1.0e-3
c lambda=1.0e3
pr=1.0e5
tr=300.
xl=2.5e6
write(*,*) ' gam=',gam
c** structure of output array
c out(1)=a1; 2=gam; 3=lambda
c 4=ts1 5=ts2 6=alb1 7=alb2
c 8=r1 9=r2 10=ts1tend 11=ts2tend
c 13=thet1 14=thet2
ikase=0
c ********* BIG LOOP ****************
do 888 nn=1,2
a1=0.1+0.2*nn
do 888 ll=1,7
c gam=1.0e-3*facg
gam=1/1024.*2.0**(ll-1)
do 888 mm=1,7
c lambda=1.0e+3*facl
lambda=64*2.0**(mm-1)
c write(*,*) '*******************************'
c write(*,*) 'GAM=',gam,', LAMBDA=',lambda,', A1=',a1
a2=1.-a1
a21=a2/a1
a12=a1/a2
c initialize variables
do i = 1,3
ts1(i)=301.
ts2(i)=300.
ta1(i)=302.
ta2(i)=300.
end do
is=1
js=2
tdelto=2.*delt/co
tdelta=2.*delt/ca
c write(*,999) ts1(js),ts2(js),ta1(js),ta2(js),r1,r2,ra1,ra2
999 format(1x,9f8.1)
c write(*,*) pbot,ptop,dp,pr,gam,bt,ct,tao,a21,lambda,lwc
ikase=ikase+1
c*** Time Loop *****
do 1000 it=1,itermx
dta=ta1(js)-ta2(js)
dto=ts1(js)-ts2(js)
call radiat(ts1(js),ts2(js),ta1(js),ta2(js),r1,r2,ra1,ra2)
call theta(ts1(js),ts2(js),ta1(js),ta2(js),demdp,demd2,deddp)
c** Note that demdp = del(theta)/grav
ts1(3)=ts1(is)+tdelto*(r1-gam*dto*cp*demdp-expo1)
ts2(3)=ts2(is)+tdelto*(r2+a12*gam*dto*cp*demdp-expo2)
c ta1(3)=ta1(is)+tdelta*(ra1-a21*gam*dto*cp*demdp-expa1)
c ta2(3)=ta2(is)+tdelta*(ra2+gam*dto*cp*deddp-expa2)
c apply Robert/Asselin filter
ts1(js)=ts1(js)*alpha1 +alpha2*(ts1(3)+ts1(is))
ts2(js)=ts2(js)*alpha1 +alpha2*(ts2(3)+ts2(is))
c if((it-1)/iprint*iprint.eq.it-1) then
if((it.eq.itermx)) then
time=(it-1)*delt/86400.
ts1tend=(r1-gam*dto*cp*demdp-expo1)*86400./co
ts2tend=(r2+a12*gam*dto*cp*demdp-expo2)*86400./co
c ta1tend=(-a21*gam*dto*cp*demdp)
c ta2tend=( gam*dto*cp*demdp)
thet1=thet(ts1,qsat(ts1,pbot),pbot)
thet2=thet(ts2,qsat(ts2,pbot),pbot)
c** structure of output array
c out(1)=a1; 2=gam; 3=lambda
c 4=ts1 5=ts2 6=alb1 7=alb2
c 8=r1 9=r2 10=ts1tend 11=ts2tend
c 12=thet1 13=thet2
c Set up array
out(1,ikase)=a1
out(2,ikase)=gam
out(3,ikase)=lambda
out(4,ikase)=ts1(js)
out(5,ikase)=ts2(js)
out(6,ikase)=alb1
out(7,ikase)=alb2
out(8,ikase)=r1
out(9,ikase)=r2
out(10,ikase)=ts1tend
out(11,ikase)=ts2tend
out(12,ikase)=thet1
out(13,ikase)=thet2
out(14,ikase)=qsat(ts1(js),pr)
c write(*,*) 'Day=',time, ', iter=',it
c write(*,*) a21,gam,dto,cp,demdp
c write(*,*) 'demdp, demd2,deddp', demdp, demd2,deddp
c write(*,*) 'lwc=',lwc,alb1, alb2
c*********x*********x*********x*********x*********x*********x*********x**********
c write(*,*) ' ts1, ts2, ta1, ta2, r1, r2, ra1,
c 1 ra2'
c write(*,999) ts1(3),ts2(3),ta1(3),ta2(3),r1,r2,ra1,ra2
c write(*,999) ts1(js),ts2(js),ta1(js),ta2(js),r1,r2,ra1,ra2
c write(*,998) ts1tend,ts2tend,ta1tend,ta2tend, thet1, thet2
998 format(1x,8f10.5)
endif
c ** Update Variables
is=3-is
js=3-js
ts1(js)=ts1(3)
ts2(js)=ts2(3)
ta1(js)=ta1(3)
ta2(js)=ta2(3)
1000 continue
888 continue
open(13,file='tropic.out',form='formatted')
c*********x*********x*********x*********x*********x*********x*********x**********
write(*,*) ' A1 gam lambda ts1 ts2 alb1
1alb2 r1 r2 ts1tend ts2tend thet1 thet2 qsat'
write(13,*) ' A1 gam lambda ts1 ts2 alb1
1alb2 r1 r2 ts1tend ts2tend thet1 thet2 qsat'
do ii=1,ikase
xkrap=out(2,ii)*out(3,ii)
write(*,789) (out(j,ii),j=1,14),xkrap
write(13,789) (out(j,ii),j=1,14),xkrap
789 format(1x,f6.1,f9.5,7f9.2,2f9.5,2f8.2,2f8.4)
enddo
stop
end
c ******************************************************
subroutine theta(ts1,ts2,ta1,ta2,demdp,demd2,deddp)
c ** This subroutine finds the theta gradients
real lwc, lambda
common /param2/ pbot,ptop,dp,gam, bt,ct,tao,a21,lambda,lwc
common /params/xkap,pr,tr,xl,cp,rgas,grav,taue,taus,taup,tauc
demdp=(thet(ts1,qsat(ts1,pbot),pbot)-thet(ts2,qsat(ts2,pbot),
1 pbot))/9.81
c 1 pbot))/dp
demd2=(thet(ta1,0.001,ptop)-thet(ts1,qsat(ts1,pbot),pbot))
1 /9.81
c 1 /dp
deddp=(thet(ts1,0.00001,ptop)-thet(ts2,0.00001,pbot))/9.81
c 1 /dp
return
end
c ******************************************************
subroutine radiat(ts1,ts2,ta1,ta2,r1,r2,ra1,ra2)
real lwc, lambda
common /param2/ pbot,ptop,dp,gam, bt,ct,tao,a21,lambda,lwc
common /params/xkap,pr,tr,xl,cp,rgas,grav,taue,taus,taup,tauc
common /heat/ beta,olr1,olr2,alb0,albgr,expo1,expo2,alb1,alb2
dta=ta1-ta2
dto=ts1-ts2
if(dto.gt.0.0) then
c ** radiation parameterization for atmosphere
ra1=-40-bt*(ta1-tao)+ct*(ts1-(ta1+29))
ra2=-200-bt*(ta2-tao)+ct*(ts2-(ta2+29))
c ** Get liquid water content
c lwc=lambda*a21*gam*abs(dto)*qsat(ts1,pr)
c ** Get albedo as function of LWC
alb2=alb0
alb1=alb0+lambda*gam*abs(dto)*qsat(ts1,pr)
if(alb1.gt.0.75) alb1=0.75
r1=400.*(1.-alb1)-olr1-beta*(ts1-300.)
r2=400.*(1.-alb2)-olr2-beta*(ts2-300.)
else
c ** here ts2 is hotter than ts1
c ** radiation parameterization for atmosphere
ra1=-200-bt*(ta1-tao)+ct*(ts1-(ta1+29))
ra2=-40-bt*(ta2-tao)+ct*(ts2-(ta2+29))
c ** Get liquid water content
c lwc=lambda*gam*abs(dto)*qsat(ts2,pr)
c ** Get albedo as function of LWC
alb1=alb0
alb2=alb0+lambda*gam*abs(dto)*qsat(ts2,pr)
if(alb2.gt.0.75) alb2=0.75
r1=400.*(1.-alb1)-olr2-beta*(ts1-300.)
r2=400.*(1.-alb2)-olr1-beta*(ts2-300.)
endif
c write(*,*) 'lwc=',lwc,', alb1,2=',alb1,alb2,', r,ra-',r1,r2,ra1,ra2
return
end
c*********x*********x*********x*********x*********x*********x*********x**********
c*************************************************************
function temp(the,rv,p)
c** Function calculates temperature given thetaE, rv and p
common /params/xkap,pr,tr,xl,cp,rgas,grav,taue,taus,taup,tauc
temp=the/((pr/p)**xkap*exp(xl*rv/(cp*tr)))
return
end
c*************************************************************
function thet(t,rv,p)
c** Function calculates thetaE given t, rv and p
common /params/xkap,pr,tr,xl,cp,rgas,grav,taue,taus,taup,tauc
thet=t*(pr/p)**xkap*exp(xl*rv/(cp*tr))
return
end
c*************************************************************
function thets(t,p)
c** Function calculates thetaEsaturate given t and p
common /params/xkap,pr,tr,xl,cp,rgas,grav,taue,taus,taup,tauc
if(t.lt.273.15) then
es=esice(t)
else
es=esat(t)
endif
rs=0.622*es/(p-es)
thets=t*(pr/p)**xkap*exp(xl*rs/(cp*tr))
return
end
c*************************************************************
subroutine plevs(p,xlp,dlp,dp)
c** Subroutine to set pressure levels
parameter(ilx=25)
dimension p(ilx),xlp(ilx),dlp(ilx),dp(ilx)
write(*,*) 'Setting Pressure Levels'
write(*,*) ' i p(i) dp(i) logp dlogp'
pmin=2000.
pmax=101300.
delpo=pmax-pmin
delp=delpo/(ilx-1)
do i=1,ilx
p(i)=pmin+(i-1.)*delp
xlp(i)=alog(p(i))
end do
do i=1,ilx-1
dlp(i)=xlp(i+1)-xlp(i)
dp(i)=p(i+1)-p(i)
end do
dlp(ilx)=0.0
do i=1,ilx
write(*,*) i,p(i),dp(i),xlp(i),dlp(i)
end do
return
end
c*************************************************************
subroutine radini(teq,p,t,sst)
c** Calculates variables needed by radiation relaxation code
parameter (ilx=25)
dimension p(ilx),t(ilx),teq(ilx)
do i=1,ilx
if(p(i).lt.12000.) then
teq(i)=t(i)
c elseif(p(i).gt.80000.) then
else
teq(i)=t(i)-10.
c teq(i)=t(i)-(p(ilx)/10000.)*2.
endif
end do
return
end
c*************************************************************
subroutine initlz(the,rt,rs,t,rv,p,sst)
c** Subroutine to set initial values of all variables
parameter (ilx=25)
dimension the(ilx),rt(ilx),rs(ilx),t(ilx),rv(ilx),
1 p(ilx)
common /params/xkap,pr,tr,xl,cp,rgas,grav,taue,taus,taup,tauc
ttrop=200.
tsurf=300.
ptrop=10000.
dtdp=(tsurf-ttrop)/(p(ilx)-ptrop)
relhum=0.80
c** Set T(p)
do i=1,ilx
if(p(i).lt.ptrop) then
t(i)=200.+10.*(ptrop-p(i))/(ptrop-p(1))
else
t(i)=200.+dtdp*(p(i)-ptrop)
endif
end do
c** Next calculate vapor mixing ratio and thetaE
write(*,*) 'index, pressure, temp., vapor mr, thetaE'
do i=1,ilx
if(p(i).lt.ptrop) then
rfrac=0.05
else
rfrac=relhum
endif
if(t(i).lt.273.) then
es=esice(t(i))
else
es=esat(t(i))
endif
rv(i)=rfrac*0.622*es/(p(i)-es)
rs(i)=0.622*es/(p(i)-es)
rt(i)=rv(i)
the(i)=t(i)*(pr/p(i))**xkap*exp(xl*rv(i)/(cp*tr))
write(*,100) i,p(i),t(i),rv(i),the(i)
100 format(1x,i3,f12.1,f7.1,e13.3,f7.1)
end do
return
end
c*************************************************************
function signum(x)
c** Hankel function
if(x.eq.0) then
signum=1.
else
signum=(abs(x)+x)*0.5/abs(x)
endif
return
end
c*************************************************************
subroutine zero(x,n)
dimension x(n)
do i=1,n
x(i)=0.0
end do
return
end
C#######################################################################
FUNCTION ESICE(TK)
C THIS FUNCTION RETURNS THE SATURATION VAPOR PRESSURE WITH RESPECT TO
C ICE ESICE (Pascals) GIVEN THE TEMPERATURE T (Kelvin). DLH 11.19.97
C THE FORMULA USED IS BASED UPON THE INTEGRATION OF THE CLAUSIUS-
C CLAPEYRON EQUATION BY GOFF AND GRATCH. THE FORMULA APPEARS ON P.350
C OF THE SMITHSONIAN METEOROLOGICAL TABLES, SIXTH REVISED EDITION,
C 1963.
DATA CTA,EIS/273.15,6.1071/
C CTA = DIFFERENCE BETWEEN KELVIN AND CELSIUS TEMPERATURE
C EIS = SATURATION VAPOR PRESSURE (MB) OVER A WATER-ICE MIXTURE AT 0C
DATA C1,C2,C3/9.09718,3.56654,0.876793/
C C1,C2,C3 = EMPIRICAL COEFFICIENTS IN THE GOFF-GRATCH FORMULA
c**** Convert to Celsius
c tc=t-273.15
IF (TK.LE.CTA) GO TO 5
ESICE = 99999.
WRITE(6,3)ESICE
3 FORMAT(' SATURATION VAPOR PRESSURE FOR ICE CANNOT BE COMPUTED',
1 /' FOR TEMPERATURE > 0C. ESICE =',F7.0)
RETURN
5 CONTINUE
C FREEZING POINT OF WATER (K)
TF = CTA
C GOFF-GRATCH FORMULA
RHS = -C1*(TF/TK-1.)-C2*ALOG10(TF/TK)+C3*(1.-TK/TF)+ALOG10(EIS)
ESI = 10.**RHS
IF (ESI.LT.0.) ESI = 0.
ESICE = ESI*100.
RETURN
END
C#######################################################################
FUNCTION ESAT(TK)
C THIS FUNCTION RETURNS THE SATURATION VAPOR PRESSURE OVER
C WATER (Pa) GIVEN THE TEMPERATURE (Kelvin). DLH 11.19.97
C THE ALGORITHM IS DUE TO NORDQUIST, W.S.,1973: "NUMERICAL APPROXIMA-
C TIONS OF SELECTED METEORLOLGICAL PARAMETERS FOR CLOUD PHYSICS PROB-
C LEMS," ECOM-5475, ATMOSPHERIC SCIENCES LABORATORY, U.S. ARMY
C ELECTRONICS COMMAND, WHITE SANDS MISSILE RANGE, NEW MEXICO 88002.
IF (TD.NE. 99999.0) THEN
C IF (TD.NE.-1001.0) THEN
c**** Convert to Celsius
c TK = TD+273.15
P1 = 11.344-0.0303998*TK
P2 = 3.49149-1302.8844/TK
C1 = 23.832241-5.02808*ALOG10(TK)
ESAT = 100.*10.**(C1-1.3816E-7*10.**P1+8.1328E-3*10.**P2-2949.076/TK)
else
esat = 0.
END IF
RETURN
END
C#######################################################################
function qsat(tk,p)
qsat=esat(tk)*0.622/p
return
end
Can someone show me how to fix this? its a fortran77 file being compiled in mingw gfortran
At least the line
ESAT = 100.*10.**(C1-1.3816E-7*10.**P1+8.1328E-3*10.**P2-2949.076/TK)
is too long for FORTRAN 77 standard. At least when the statement starts at column 7. In your code it appears to start earlier, but that is wrong.
Break it,
ESAT = 100.*10.**(C1-1.3816E-7*10.**P1+
* 8.1328E-3*10.**P2-2949.076/TK)
or use an option like
-ffixed-line-length-132
to make the limit larger (it is non-standard!).
Also many of your statements appear to start on earlier column than 7. This may be a copy-paste error to this page, it may be due to the non-conforming tab characters the compiler warns about. If it is not the case, correct it too, they must start at column 7 or further. For example, this is very strange:
IF (TD.NE. 99999.0) THEN
C IF (TD.NE.-1001.0) THEN
There may be other errors, but your code is simply too long and cannot be compiled by copy-paste.
Related
How do I use modules correctly in a Fortran program?
I built a speed, distance, and time calculator. I thought that it would be cool if you could go back to the main menu and calculate time after your original calculation (as an example). How would I do this by using modules? Here are the modules I have created: module menu real :: s ! speed real :: d ! distance real :: t ! time real :: gg ! this is how I am going to switch between distance, time, and speed print *, 'Press 1 for speed, 2 for distance, and 3 for time' read*, gg end menu module speed print *, 'Input distance in metres' read *, d print *, 'Input time in seconds' read *, t s = d / t print *, 'Speed is ', s end speed module stay or leave print *, 'Press 4 to go back to menu, or press 5 to exit the console' read *, gg end stay or leave module distance print *, 'Input speed in metres per second' read *, s print *, 'Input time in seconds' read *, t d = s * t print*, 'Distance is ', d end distance module time print *, 'Input distance in metres' read *, d print *, 'Input speed in metres per second' read *, s t = d / s print*, 'Time is ', s end time
You are using module as a subroutine. A module is a collection of related subroutines, user types and other related data. There is no need to use modules in this example (at least not in the way it is shown above). But if you had to use modules I have included an example below. The module definition contains the following subroutines time_from_distance_and_speed() distance_from_speed_and_time() speed_from_time_and_distance() and three common variables t, d, s used in the calculations. Although in general it not recommended re-using the same variables in different routines, this is done here for illustrative purposes to show how "global" variables can be defined in the module level. Module Here the module contains the variable definitions which are common to the procedures it contains. It also defines the three calculation processes. module kinematics implicit none real :: t, d, s contains subroutine time_from_distance_and_speed() print *, 'Input distance in metres' read *, d print *, 'Input speed in metres per second' read *, s t = d / s print*, 'Time is ', s end subroutine subroutine distance_from_speed_and_time() print *, 'Input speed in metres per second' read *, s print *, 'Input time in seconds' read *, t d = s * t print*, 'Distance is ', d end subroutine subroutine speed_from_time_and_distance() print *, 'Input distance in metres' read *, d print *, 'Input time in seconds' read *, t s = d / t print *, 'Speed is ', s end subroutine end module Program Here the main program uses the module defined above and calls the appropriate method depending on the user input. program bike use kinematics integer :: gg do while(.true.) print *, 'Press 1 for speed, 2 for distance, and 3 for time' read*, gg if(gg == 1) then call speed_from_time_and_distance else if(gg == 2) then call distance_from_speed_and_time else if(gg == 3) then call time_from_distance_and_speed end if print *, 'Press 5 to exit the console, anything else will repeat' read *, gg if(gg== 5) then exit end if end do end program
Fortran read SIGSEGV segmentation fault
I'm not familiar with Fortran, but I had to use my advisor's old code but it didn't work, and I could track down it to a minimal working example. hello.f is following: implicit none character*200 rec integer var,idum real*4 rdum call xparse('-t0',1,1,'required',rec,idum,rdum) print *, rec read(rec,'(i6)') var print *, var END And extra.f is following: c------------------------------------------------------------------ subroutine xparse(cc,nth,ifo,req,carg,iarg,rarg) c------------------------------------------------------------------ character*(*) cc,req,carg character*256 rec c iver=0 lcc=len(cc) na=iargc() ith=0 do 100 ia=1,na call getarg(ia,rec) if(rec(1:15).eq.'-xparse_verbose') iver=1 lrec=ilen(rec,256) if(lrec.eq.lcc) then if(rec(1:lcc).eq.cc(1:lcc)) then if(iver.eq.1)write(0,'(a,a)')'xparse ,parsing:',rec(1:lcc) c if(nth.le.0) then iarg=1 return endif c ith=ith+1 if(ith.eq.nth) then c if(ia.eq.na) then write(0,*)'parse error : missing value for ',cc endif call getarg(ia+1,rec) lrec=ilen(rec,256) if(iver.eq.1)write(0,'(a,a)')'xparse, string:',rec(1:lrec) if(ifo.eq.1) then if(iver.eq.1)write(0,'(a,a)')'xparse, character:',rec(1:lrec) carg=rec else if(ifo.eq.2) then s=gets(rec) if(s.ge.0.0)iarg=s+0.1 if(s.lt.0.0)iarg=s-0.1 if(iver.eq.1)write(0,*)'xparse, integer:',iarg else if(ifo.eq.3) then rarg=gets(rec) if(iver.eq.1)write(0,*)'xparse, real:',rarg endif return c endif endif endif 100 continue c if(req(1:8).eq.'required') then write(0,*)'parse error : cant find required arg: ',cc stop endif end c------------------------------------------ real function gets(cc) c------------------------------------------ c c decodes integer or floating f format c from character string c character*(*) cc nn=len(cc) c gets=0.0 fak=1. ief=0 l1=0 l2=0 do 200 i=1,nn if(cc(i:i).eq.'e'.or.cc(i:i).eq.'E')ief=i if(cc(i:i).eq.'d'.or.cc(i:i).eq.'D')ief=i if(l1.eq.0.and.cc(i:i).ne.' ')l1=i if(cc(i:i).ne.' ')l2=i if(cc(i:i).eq.' '.and.l2.gt.0) goto 201 200 continue 201 continue nn=l2 if(ief.gt.0) then lex=l2-ief iex=-9999999 if(lex.eq.1)read(cc(ief+1:l2),'(i1)',err=900) iex if(lex.eq.2)read(cc(ief+1:l2),'(i2)',err=900) iex if(lex.eq.3)read(cc(ief+1:l2),'(i3)',err=900) iex if(lex.eq.4)read(cc(ief+1:l2),'(i4)',err=900) iex if(lex.eq.5)read(cc(ief+1:l2),'(i5)',err=900) iex if(iex.gt.-999999) then if(iex.lt.0)fak=1./( 10.**(-iex) ) if(iex.gt.0)fak=10.**iex else write(0,*)'gets: cannot read ',cc endif nn=ief-1 endif c sig=1. ss=0. tt=1. ip=0 do 100 l=1,nn if(cc(l:l).ne.' ') then if(cc(l:l).eq.'.') then ip=1 else if(cc(l:l).eq.'-') then sig=-1. else c read(cc(l:l),'(i1)',err=900) ii ii=ichar(cc(l:l))-48 if(ii.lt.0.or.ii.gt.9) goto 109 if(ip.eq.0) then ss=10.*ss+float(ii) else tt=0.1*tt ss=ss+tt*float(ii) endif endif endif 100 continue 109 continue gets=ss*sig*fak return 900 continue write(0,*)' gets: error reading formatted integer:' write(0,*)nn write(0,'(a,a,a)')'$',cc,'$' return end c------------------------------------- integer function ilen(c,m) c------------------------------------- character*80 c k=1 do 100 i=1,m if(c(i:i).ne.' '.and.c(i:i).ne.char(0))k=i 100 continue ilen=k jlen=k return end If I do gfortran hello.f extra.f ./a.out -t0 10800 I get the error 10800 Program received signal SIGSEGV: Segmentation fault - invalid memory reference. Backtrace for this error: #0 0x10a01735c #1 0x10a0166f3 #2 0x7fff7376cb5c #3 0x10a15b340 #4 0x10a15bd2d #5 0x10a15978f #6 0x10a00c917 #7 0x10a00c9e5 Segmentation fault: 11 That read function(?) is the one frequently used in the code to read user input (like Python's sys.argv) but I can't see why it fails. I'm using GNU Fortran (Homebrew GCC 9.3.0_1) 9.3.0, MacOS Mojave 10.14.6.
There is a bug in the function ilen. Consider character*80 c k=1 do 100 i=1,m if(c(i:i).ne.' '.and.c(i:i).ne.char(0))k=i 100 continue The variable (dummy argument) c is declared to be of length 80, but in the loop the substring c(81:81) is surely attempted to be accessed if m is bigger than 80 (which it is when called in the program). This is incorrect. You can index c up to position 80 with do 100 i=1,80 ... or up to its length: do 100 i=1,len(c) ... Alternatively, you can make c have length 256 or not (necessarily) 80: c Have the length of the dummy argument assumed character*(*) c or c Have the length given by the argument m character*(m) c There are also the modern ways to write character declarations such as character(len=*) c and character(len=m) c
Fortran - Jump other subroutine
I am trying to jump other subroutine in Fortran code. I used the return function but it is not working in some cases. Is there any way to jump to other subroutine. I made a simple example to define the problem. If the condition is in the same subroutine, I can use goto label but I need to jump different subroutine. If the condition is correct (case = .True.), I don't want to calculate that subroutine so I will skip that subroutine, I will start to use the new data. For example, if i=3 and case=true, the program shouldn't print a=8 in the 3rd loop and jump the do loop in subroutine abc. ---------------------------------------------- subroutine abc() do i=1, 5 !if case is true, start to program from here. call vector () end do end subroutine ------------------------------------- subroutine vector() if (case = .True.)then *****JUMP call vector in main program ***** print *,"skip and jump " return a= 8 print *, a else b= 9 print *, b print *, "continue the process " end if end subroutine ------------------------------------------------ -----output should be------- 9 9 skip and jump 9 9
Syntax error of DATA statement in Fortran 90
I have to compute few complex integrals and for this purpose I got from my supervisor old program written in Fortran 77. However I have few problems with it. Mostly associated with syntax errors of DATA Statement. This is a part of code with a function calculating real integrals: FUNCTION CAUSSA(F,A,B,EPS) IMPLICIT DOUBLE PRECISION (A-H,O-Z) external f REAL :: W(12),X(12) DATA CONST /1.0D-12/ DATA W & 1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,& 2 0.36268 37833 7836 , 0.02715 24594 1175 , 0.06225 35239 3864 ,& 3 0.09515 85116 8249 , 0.12462 89712 5553 , 0.14959 59888 1657 ,& 4 0.16915 65193 9500 , 0.18260 34150 4492 , 0.18945 06104 5506 / DATA X & 1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,& 2 0.18343 46424 9565 , 0.98940 09349 9165 , 0.94457 50230 7323 ,& 3 0.86563 12023 8783 , 0.75540 44083 5500 , 0.61787 62444 0264 ,& 4 0.45801 67776 5722 , 0.28160 35507 7925 , 0.09501 25098 3763 / DELTA=CONST*DABS(A-B) CAUSSA=0.d0 AA=A 5 Y=B-AA IF(DABS(Y) .LE. DELTA) RETURN 2 BB=AA+Y C1=0.5*(AA+BB) C2=C1-AA S8=0.d0 S16=0.d0 DO 1 I=1,4 U=X(I)*C2 1 S8=S8+W(I)*(F(C1+U)+F(C1-U)) DO 3 I = 5,12 U=X(I)*C2 3 S16=S16+W(I)*(F(C1+U)+F(C1-U)) S8=S8*C2 S16=S16*C2 IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4 CAUSSA= CAUSSA+S16 A=BB GO TO 5 4 Y=0.5*Y IF(DABS(Y) .GT. DELTA) GO TO 2 write(2,7) write(5,7) 7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED) CAUSSA=0.d0 RETURN END The result of compilation is following: sample.f90:11: 1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,& 1 Error: Syntax error in DATA statement at (1) sample.f90:17: 1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,& 1 Error: Syntax error in DATA statement at (1) I use gfortran version 4.4.7. I tried to rewrite those arrays but the result is always the same. Although this function is not the best for integrating, I still need it. Without it, that old program is collapsing. I would appreciate any advice.
If you want to compile this as free form source, there are two things you will probably need to change I am pretty sure that labels are illegal in continuation lines, so they should be removed gfortran will misinterpreted the spaces between sections of the floating point numbers, so those also should be removed. Something like this: DATA W & /0.10122853629037 , 0.22238103445337 , 0.31370664587788 ,& 0.36268378337836 , 0.02715245941175 , 0.06225352393864 ,& 0.09515851168249 , 0.12462897125553 , 0.14959598881657 ,& 0.16915651939500 , 0.18260341504492 , 0.18945061045506 / should probably compile correctly [note written in browser and not tested].
Your original code was erroneously mixing both free-form and fixed-source format. Line continuations in free-form are performed by using a trailing ampersand character, &, rather than entering a character in column 6 of the following line. In fixed-source form, the first six columns are reserved for statement labels, with column 1 also used to indicate comment lines. In modern code, using structured control statements (such as select case or if-then-else) statement labels are uncommon. The first five columns are therefore wasted because they are rarely used. Here is the same code in free-form and fixed-source format: program main use ISO_Fortran_env, only: & compiler_version, & compiler_options ! Explicit typing only implicit none ! Variable declarations double precision :: a, b, eps, x a = 1.0d0 b = 2.0d0 eps = epsilon(a) x = caussa(my_func, a, b, eps) print '(/4a/)', & ' This file was compiled using ', compiler_version(), & ' using the options ', compiler_options() contains function my_func(arg) result (return_value) ! Dummy arguments double precision, intent (in) :: arg double precision :: return_value return_value = arg * 42.0d0 end function my_func function caussa(f,a,b,eps) use ISO_Fortran_env, only: & stderr => ERROR_UNIT implicit double precision (a-h,o-z) external f integer :: i real :: w(12),x(12) data const /1.0d-12/ data w & /0.10122853629037, 0.22238103445337, 0.31370664587788 ,& 0.36268378337836, 0.02715245941175, 0.06225352393864 , & 0.09515851168249, 0.12462897125553, 0.14959598881657 , & 0.16915651939500, 0.18260341504492, 0.18945061045506 / data x & /0.96028985649753, 0.79666647741362, 0.52553240991632, & 0.18343464249565, 0.98940093499165, 0.94457502307323, & 0.86563120238783, 0.75540440835500, 0.61787624440264, & 0.45801677765722, 0.28160355077925, 0.09501250983763 / delta=const*dabs(a-b) caussa=0.d0 aa=a 5 y=b-aa if (dabs(y) <= delta) return 2 bb=aa+y c1=0.5*(aa+bb) c2=c1-aa s8=0.d0 s16=0.d0 do 1 i=1,4 u=x(i)*c2 1 s8=s8+w(i)*(f(c1+u)+f(c1-u)) do 3 i = 5,12 u=x(i)*c2 3 s16=s16+w(i)*(f(c1+u)+f(c1-u)) s8=s8*c2 s16=s16*c2 if (dabs(s16-s8)>eps*dabs(s16)) go to 4 caussa = caussa+s16 a = bb go to 5 4 y = 0.5*y if (dabs(y) > delta) go to 2 write(2,7) write(stderr,7) ! ! 7 format(1x,35hcaussa...too high accuracy required) ! Hollerith format specifier is a Fortran 95 deleted feature ! 7 format(1x, 'caussa...too high accuracy required') caussa=0.d0 end function caussa end program main Here's the fixed-form version PROGRAM MAIN USE ISO_FORTRAN_ENV, ONLY: 1 COMPILER_VERSION, 2 COMPILER_OPTIONS C EXPLICIT TYPING ONLY IMPLICIT NONE C VARIABLE DECLARATIONS DOUBLE PRECISION :: A, B, EPS, X A = 1.0D0 B = 2.0D0 EPS = EPSILON(A) X = CAUSSA(MY_FUNC, A, B, EPS) PRINT '(/4A/)', 1 ' THIS FILE WAS COMPILED USING ', COMPILER_VERSION(), 2 ' USING THE OPTIONS ', COMPILER_OPTIONS() CONTAINS FUNCTION MY_FUNC(ARG) RESULT (RETURN_VALUE) C DUMMY ARGUMENTS DOUBLE PRECISION, INTENT (IN) :: ARG DOUBLE PRECISION :: RETURN_VALUE RETURN_VALUE = ARG * 42.0D0 END FUNCTION MY_FUNC FUNCTION CAUSSA(F,A,B,EPS) USE ISO_FORTRAN_ENV, ONLY: 1 STDERR => ERROR_UNIT IMPLICIT DOUBLE PRECISION (A-H,O-Z) EXTERNAL F INTEGER I REAL :: W(12), X(12) DATA CONST /1.0D-12/ DATA W 1 /0.10122 85362 9037, 0.22238 10344 5337, 0.31370 66458 7788, 2 0.36268 37833 7836, 0.02715 24594 1175, 0.06225 35239 3864, 3 0.09515 85116 8249, 0.12462 89712 5553, 0.14959 59888 1657, 4 0.16915 65193 9500, 0.18260 34150 4492, 0.18945 06104 5506 / DATA X 1 /0.96028 98564 9753, 0.79666 64774 1362, 0.52553 24099 1632, 2 0.18343 46424 9565, 0.98940 09349 9165, 0.94457 50230 7323, 3 0.86563 12023 8783, 0.75540 44083 5500, 0.61787 62444 0264, 4 0.45801 67776 5722, 0.28160 35507 7925, 0.09501 25098 3763 / DELTA=CONST*DABS(A-B) CAUSSA=0.D0 AA=A 5 Y=B-AA IF(DABS(Y) .LE. DELTA) RETURN 2 BB=AA+Y C1=0.5*(AA+BB) C2=C1-AA S8=0.D0 S16=0.D0 DO 1 I=1,4 U=X(I)*C2 1 S8=S8+W(I)*(F(C1+U)+F(C1-U)) DO 3 I = 5,12 U=X(I)*C2 3 S16=S16+W(I)*(F(C1+U)+F(C1-U)) S8=S8*C2 S16=S16*C2 IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4 CAUSSA= CAUSSA+S16 A=BB GO TO 5 4 Y=0.5*Y IF(DABS(Y) .GT. DELTA) GO TO 2 WRITE(2,7) WRITE(STDERR,7) C C 7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED) C HOLLERITH FORMAT SPECIFIER IS A FORTRAN 95 DELETED FEATURE C 7 FORMAT(1X, 'CAUSSA...TOO HIGH ACCURACY REQUIRED') CAUSSA=0.D0 RETURN END FUNCTION CAUSSA END PROGRAM MAIN With free-form, the concept of “significant blanks” was introduced. In fixed-source, blanks were insignificant in most contexts. Here is a sample of a fixed-source statement showing what are now considered significant blanks followed by an equivalent statement without the blanks: DO N = 1, MAX ITER S DO N = 1, MAXITERS Notice how we rewrote DATA W 1 /0.10122 85362 9037, blah blah as data w & /0.10122853629037, blah blah
converting a Peng Robinson equation code in fortran to C++
i would like someone to assist in converting this code to C++ c ---------------------------------------------------------------------- c Calculate pressure based on the generalized Peng-Robinson equation of state. c for water. c Variables Used ... c T ... temperature (K) c P ... vapor pressure (MPa) c V ... volume (m^3/kmol) c ---------------------------------------------------------------------- c Instructor: Nam Sun Wang c ---------------------------------------------------------------------- common /cblock/T c Program Header ------------------------------------------------------- print *, 'This program calculates pressure based on the' print *, 'generalized Peng-Robinson equation of state for water.' print *, ' ' c Temperature ---------------------------------------------------------- print *, 'Enter temperature (K): ' read *, T c Generate a table of P at different values of V in 0.5 increments. print *, ' ' print *, '------------------------' print *, ' Volume Pressure ' print *, '(m^3/kmol) (MPa) ' print *, '------------------------' c xx.x123456789012345678 --- ruler do i=1, 100 V = 0.5*float(i) print 650, V, P(V) end do c Some formats --------------------------------------------------------- 650 format(f7.1, 1p, e18.6) end c ---------------------------------------------------------------------- function P(V) c ---------------------------------------------------------------------- c Calculate pressure based on the generalized Peng-Robinson equation of state. c for water. c ---------------------------------------------------------------------- common /cblock/T c Gas Constant --------------------------------------------------------- R = 8.314E-3 ! (in MPa m3/kmol K) c Critical parameters for water ---------------------------------------- Tc = 647.3 ! (critical temperature in K) Pc = 22.048 ! (critical pressure in MPa) w = 0.344 ! (acentric factor, dimensionless) c Peng-Robinson EOS parameters ----------------------------------------- xk = 0.37464 + 1.54226*w - 0.26992*w*w alpha = ( 1. + xk*(1.-sqrt(T/Tc)) )**2 a = 0.45724*R*R*Tc*Tc*alpha/Pc b = 0.07780*R*Tc/Pc P = R*T/(V-b) - a/(V*(V+b)+b*(V-b)) end
Here are Some conversions for you, have a go and then post your results. We can then help you complete it. a message print *, '...' replace with cout << "..." a counted loop do i=1, 100 ... end do replace with for(int i = 1; i <= 100; ++i) { .... } a comment .... ! A comment replace with ....; // a comment a variable X = 99.879 replace with float X = 99.879 a function function P(V) . . . P = .... ! the result replace with double P(double V){ . . . return ....; // the result }
I know this is late but I came here looking for an answer and found another solution. Try the package f2c. I just used it on your code sample and it worked perfectly. Although it is a bit ugly as it links to libraries that emulate Fortran functions like print but you could just use the main logic part and do the I/O yourself.