Conditional ploting in Gnuplot using fortran 90 - fortran

i have a truss bridge that i want to draw using fortran 90 and Gnuplot , but the truss elements should change color if the corresponding array element is bigger or smaller than zero
open(10,file='plot_2D.plt')
write(10,*) 'set title " truss"'
write(10,*) 'set xrange [0:300]'
write(10,*) 'set yrange [0:40]'
write(10,*) 'set xlabel "x [U]"'
write(10,*) 'set ylabel "y [U]"'
write(10,*) 'set key noautotitle'
write(10,*) 'plot "1.txt" if (x(1) > 0 ) {with line 7} else { with line lt 3 } '
write(10,*) 'pause -1 "Hit return to continue"'
close(10)
ofcourse i have 1.txt up to 222.txt
but i just put one here because it is repetitive process
but i dont get any plot ,
what is my mistake ?

It is not clear what exactly you mean by x(1) > 0 since there is no function x() defined. Assuming that x(1) means data value in column 1, then instead of
write(10,*) 'plot "1.txt" if (x(1) > 0 ) {with line 7} else { with line lt 3 } '
the correct syntax is
write(10,*) 'plot "1.txt" using 1:2:($1>0 ? 7 : 3) with lines linecolor variable'

Related

Reading three specific numbers in a text file and writing them out

I have a problem how to print only specific three numbers, which are in a file with no format. I have no idea how to read it and print because if I use read from higher i, it does not start reading e.g. for i = 4, the line 4. I need only numbers 88.98, 65.50, and 30.
text
678 people
450 girls
22 old people
0 cats
0 dogs
4 girls blond
1 boy blond
1 old man
0 88.9814 xo xi
0 65.508 yo yi
0 30 zo zi
I tried this, but this is not working at all.
program souradnice
implicit none
integer :: i, k
character*100 :: yo, zo, line, name, text
real :: xo
open(10,file="text.dat", status='old')
do i=20,20
read(10,fmt='(a)') line
read(unit=line, fmt='(a100)') text
if(name=="xo") then
print *, trim(text)
endif
enddo
close(10)
end program souradnice
You need to read the whole file line by line, and check each line to see if it's the one you want, e.g. by using the index intrinsic. For example,
program souradnice
implicit none
character(100) :: line
character(5) :: matches(3)
real :: numbers(3)
character(10) :: dummy
integer :: i, ierr
! Substrings to match to find the relevant lines
matches = ["xo xi", "yo yi", "zo zi"]
open(10,file="text.dat", status='old')
do
! Read a line from the file, and exit the loop if the file end is reached.
read(10,fmt='(a)',iostat=ierr) line
if (ierr<0) then
exit
endif
do i=1,3
! Check if `line` matches any of the i'th line we want.
if (index(line, matches(i))>0) then
! If it matches, read the relevant number into `numbers`.
read(line,*) dummy, numbers(i)
endif
enddo
enddo
write(*,*) numbers
end program

Fortran error with the FORMAT statement

I'm trying to compile some Fortran code but I keep getting errors with the FORMAT statement. It says I'm missing brackets and characters but it looks fine to me. I am compiling it with silverfrost. The code is shown below:
! PROGRAM TO SOLVE DEEP-BED DRYING MODEL
!
! BASIC STATEMENTS
!
CHARACTER*20 FiIe1, File2
COMMON AMo
COMMON /DENS/ Pmo, Pme
COMMON /THICK/ dxo, Dxe
DIMENSION AM1(50), AM2(50), T(50), Gs(51), Vs(51), Ts(51), Dx(50), X(50)
!
!To define a number of statement functions
AMe(Ts)=0.62*EXP(-1.116*(Ts-100)**0.3339)
A(Ts, Vs)=(1.2925-0.00058*Ts) * (0.9991-0.0963*Vs)
AK(Ts, Vs)=(0.00273*Ts-0.2609)*(2.0984*Vs+0.2174)
AN(Ts)=0.00222*Ts+0.9599
Ps(Ts)=0.7401-0.001505*Ts
!
!INPUT SECTION OF THE PROGR.A,M
!
PRINT*, 'Input the mass of the sample (g) :'
READ*, Wo
PRINT*, 'Input the initial moisture content (db):'
READ*, AMo
PRINT*, 'lnput the depth of the sample bed (mm):'
READ*, Xo
PRINT*, 'Input the number of layers in the bed:'
READ*, Nx
PRINT*, 'Input the steam temperature at inlet (oC):'
READ*, Tso
PRINT*, 'input the steam flow rate at inlet (kg/(m2.s)):'
READ*, Gso
PRINT*, 'lnput the expected drying time (min):'
READ*, Timeo
PRINT*, 'lnput the time interval- (min) :'
READ*, Dt
!
! TO DEFINE AND OPEN DATA FILES
!
PRINT*, 'Name for the file recording the simulation +process:'
READ*, File1
OPEN (1, FILE=File1)
PRINT*, 'Name for the file recording major data:'
READ*, File2
OPEN (2, FILE=File2)
!
! TO WRITE INPUTTED PARAMETERS IN THE DATA FILES
!
WRITE (1, *) 'Mass of sample:', Wo, ' g'
WRITE (1, *) 'Initial moisture content:', AMo, ' kg/kg'
WRITE (1, *) 'Depth of sample bed:', Xo, 'mm'
WRITE (1, *) 'Number of layers in sample bed:', Nx
WRITE (1, *) 'Steam temperature at inlet', Tso, 'deg C'
WRITE (1, *) 'Steam flow rate at inlet', Gso, 'kg/m2s'
WRITE (1, *) 'Expected drying time', Timeo, ' min'
WRITE (1, *) 'Time interval:', Dt, ' min'
!
WRITE (2, *) 'Mass of sample', Wo, 'g'
WRITE (2, *) 'Initial moisture content', AMo, 'kg/kg'
WRITE (2, *) 'Depth of sample bed', Xo, 'mm'
WRITE (2, *) 'Number of layers in sample bed', Nx
WRITE (2, *) 'Steam temperature at inlet', Tso, ' deg C'
WRITE (2, *) 'Steam flow rate at inlet', Gso, ' kg/m2*s'
WRITE (2, *) 'Expected drying time', Timeo, ' min'
WRITE (2, *) 'Time interval:', Dt, ' min'
!
!BASIC CALCULATION BASED ON THE INPUT DATA
!
Dxo=Xo/1000/Nx
Dxe=0.867*Dxo
D1=0.066
Pmo=4*(Wo/l000)/(3.14159*D1**2*(Xo/1000)*(1+AMo))
Pme=Pmo/0.867
AMeo=AMe(Tso)
NT=NINT(Timeo/Dt)
Pso=Ps(Tso)
Vso=Gso/Pso
!
!TO SET VALUES FOR SOME PHYSTCAL AND THERMODYNAMTC PROPERTIES
!
Cs=2000
Cw1=4193
Cw=4313
C=1245
!
!TO CALCULATE THE INTTIAL MOISTURE CONTENT CONSIDERING STEAM CONDENSATION
!
AMo1=AMo+(C+Cw1*AMo)/(2257000+Cs*(Tso-100))*(100-10)
!
!TO SET JUDGE CRITERION FOR TERMINATING THE DRYING OF A LAYER
!(A small difference between moisture content and equilibrium moisture content)
DM=0.0001
!
!MAJOR DERIVATION FOR DRYING SIMULATION
!
J=0
Time=0
m=1
!
WRITE(2, 100)
100 FORMAT(4H J, 9H T(min), 8H M(db),7H Gs , 10H Ts(C) ,9H Front1, 5H L1, 9H Front2, 5h L2, 9H Depth)
!
200 m5=m-1
IF (J .GT. Nt) GO to 800
!
PRINT*, ' '
PRINT*, ' '
PRINT*, 'Time inverval:', J, ' Drying time:', Time, ' min'
WRITE(1, x) ' '
WRITE(1, *) 'Time interval:', J, ' Drying time:', Time, ' min'
WRITE(*, 300)
WRITE(1, 300)
300 FORMAT(1x, 3H, I, 7H, X(i), 8H M(i), 10H T(i), 10H Gs(i), 8H Ts(i))
!
AveM=0
!
! For dried region
!
IF(m .GT. 1) THEN
DO 500 i=1, m-1
Dx(i)=Dxe
X(i)=(i-0.5)*Dxe
AM1(i)=AM2(i)
T(i)=Tso
Gs(i)=Gso
Vs(i)=Vso
Ts(i)=Tso
AveM=AveM+AM1(i)
WRITE(*, 400) i, X(i), AM1(i), T(i), Gs(i), Ts(i)
WRITE(1, 400) i, X(i), AM1(i), T(i), Gs(i), Ts(i)
400 FORMAT(1X, I3, 2X, F6.4, 2X, F6.4, 2X, F8.3, 2X, F7.3, 2X, F7.3)
500 CONTINUE
ENDIF
! Calculation of the drying front position
IF (m .EQ. l) THEN
X1=-1
No1=-1
ELSE
Xl=X(m-1)+Dx(m-1)/2
No1=m-1
ENDIF
!
IF (m .GT. Nx) GO TO 900
!
Ts(m)=Tso
Vs(m)=Vso
L=0
DO 600 i=m, Nx
IF(L .NE.0) GO TO 510
!
! For drying region
!
If (J .EQ. O) THEN
Am1(i)=AMo1
Else
AM1(i)=AM2(i)
ENDIF
Dx(i)=Dxx(AM1(i))
IF (i .EQ. 1) THEN
X(i)=Dx(i)/2
ELSE
X(i)=X(i-1)+Dx(i-1)/2+Dx(i)/2
ENDIF
!
! To define transition variables
!
AMe5=AMe(Ts(i))
A5=A(Ts(i),Vs(i))
AK5=AK(Ts(i),Vs(i))
AN5=AN(Ts(i))
Ps5=Ps(Ts(i))
P5=P(AMl(i))
Dt5=Dt* 60
!
! Derivation
!
AMmax=A5*(AMo-AMe5)/EXP((AN5-1)/AN5)+AMe5
IF (AM1(i) .GE. AMmax) THEN
AM2(i)=AM1(i)-Dt5*AK5*AN5*(AMmax-AMe5)*(ALOG(A5*(AMo-AMe5)/(AMmax-AMe5))/AK5)**((AN5-1)/AN5)/60
ELSE
AM2(i)=AM1(i)-Dt5*AK5*AN5*(AM1(i)-AMe5)*(ALOG(A5*(AMo-AMe5)/(AM1(i)-AMe5))/AK5)**((AN5-1)/AN5)/60
ENDIF
DR=(AM2(i)-AM1(i))/Dt5
!
IF (AM1(i) .GE. AMo) THEN
T(i)=100
DerT=0
ELSE
T(i)=Tso-(Tso-100)*(AM1(i)-AMeo)/(AMo-AMeo)
DerT=-(Tso-l00)/(AMo-AMeo)*DR
ENDIF
!
Gs(i)=Vs(i)*Ps5
Gs(i+l)=Gs(i)-Dx(i)*P5*DR
Vs(i+1)=Gs(i+1)/Ps5
Hv5=Hv(AMl(i), T(i))
Ts(i+1)=Ts(i)+Dx(i)*P5*(Hv5+Cs*(Ts(i)-T(i)))/(Gs(i)*Cs)*DR-Dx(i)*P5*(C+Cw*AMl(i))/(Gs(i)*Cs)*DerT
!
! To find the first layer in wet region
!
IF (Ts(i+l) .LE. l00) THEN
Ts(i+1)=100
L=i
ENDIF
!
! To check if the layer has been dried to equilibrium
!
IF ((AM2(i)-AMeo) .LE. DM) THEN
m5=i
AM2(i)=AMeo
ENDIF
GO TO 520
!
! For wet region
!
510 AM1(i)=AMo1
AM2(i)=AMo1
T(i)=100
Gs(i+l)=Gs(i)
Vs(i+1)=Vs(i)
Ts(i+1)=100
!
Dx(i)=Dxx(AM1(i))
IF (i .EQ. 1) THEN
X(i)=Dx(i)/2
ELSE
X(i)=X(i-1)+Dx(i-1)/2+Dx(i)/2
ENDIF
!
520 AveM=AveM+AM1(i)
WRITE(*, 400) i, X(i), AM1(i), T(i), Gs(i), Ts(i)
WRITE(1, 400) i, X(i), AM1(i), T(i), Gs(i), Ts(i)
600 CONTINUE
!
! Calculation of wet front position
IF (L .EQ. O) THEN
X2=-1
No2=-1
ELSE
X2=X(L)+Dx(L)/2
No2=L+1
ENDIF
!
AveM=AveM/Nx
Depth=X(Nx)+Dx(Nx)/2
!
WRITE(*, 100)
WRITE(*, 700) J, Time, AveM, Gs(Nx*1), Ts(Nx*1), XI, No1, X2, No2, Depth
WRITE (2, 700) J, Time, AveM, Gs(Nx+1), Ts(Nx*1), X1, No1, X2, No2, Depth
700 FORMAT(I4, 2X, F7.3, 2X, F6.4, 2X, F6.4, 2X, F7.3, 2X, F7.4, 2x, I3, 2X, F7.4, 2X, I3, 2x, F7.4)
!
J=J+1
Time=Time+Dt
m=m5+1
GO TO 200
!
800 PRINT*, ' '
PRINT*, 'The drying time was up to the specified time.'
PRINT*, 'The drying simulation was stopped.'
PRINT*, 'The sample was not dried to equilibrium'
WRITE(1,*) ' '
WRITE(1,*) 'The drying time was up to the specified time.'
WRITE(1,*) 'The drying simulation was stopped'
WRITE(1,*) 'The sample was not dried to equilibrium'
WRITE(1,*) ' '
WRITE(2,*) 'The drying time was up to the specified time'
WRITE(2,*) 'The drying simulation was stopped'
WRITE(2,*) 'The drying simulation was stopped'
WRITE(2,*) 'The sample was not dried to equilirbium'
GO TO 910
!
900 No2=-1
X2=-1
AveM=AveM/Nx
WRITE(*, 100)
WRITE(*, 700) J, Time, AveM, Gs(Nx+1), Ts(Nx+1), X1, No1, X2, No2, Depth
WRITE(2, 700) J, Time, AveM, Gs(Nx+1), Ts(Nx+1), X1, No1, X2, No2, Depth
!
PRINT*, ' '
PRINT*, 'The sample was dried to equilibrium'
PRINT*, 'The drying simulation was stopped.'
WRITE(1,*) ' '
WRITE(1,*) 'The sample was dried to equilibrium'
WRITE(1,*) 'The drying simulation was stopped'
WRITE(2,*) ' '
WRITE(2,*) 'The sample was not dried to equilirbium'
WRITE(2,*) 'The drying simulation was stopped'
!
910 CLOSE(1)
CLOSE(2)
END
!
!**********************************************************************************
!
! EXTERNAL FUNCTION FOR LATENT HEAT OF EVAPORATION
!
FUNCTION Hv(AM, T)
Hfg=2257000-2916.7*(T-100)
IF (AM .GE. 0.2) THEN
Hv=Hfg
ELSE
Hv=Hfg*(1+EXP(-19.9*AM))
ENDIF
RETURN
END
!
! EXTERNAL FUNCTION FOR BULK DENSITY
!
FUNCTION P(AM)
COMMON AMo/DENS/ Pmo, Pme
IF (AM .GE. AMo) THEN
P=Pmo
ELSE IF (AM .LT. 0.11) THEN
P=Pme
ELSE
P=Pmo-(Pmo-Pme)*(AMo-AM)/(AMo-0.11)
ENDIF
RETURN
END
!
! EXTERNAL FUNCTION FOR LAYER THICKNESS
!
FUNCTION Dxx(AM)
COMMON AMo/THICK/ Dxo, Dxe
IF (AM .GE. AMO) THEN
Dxx=Dxo
ELSE IF (AM .LT. 0.11) THEN
Dxx=Dxe
ELSE
Dxx=Dxo-(Dxo-Dxe)*(AMo-AM)/(AMo-0.11)
ENDIF
RETURN
END
!
!****************************************************************************************
And the errors are shown below:
Compiling and linking file: SHSDRYING.F95
C:\Users\steva\Desktop\SHSDRYING.F95(104) : error 58 - Unpaired right bracket(s)
C:\Users\steva\Desktop\SHSDRYING.F95(45) : error 259 - Scalar, default-kind, CHARACTER expression expected for the FILE keyword
C:\Users\steva\Desktop\SHSDRYING.F95(45) : warning 868 - Opening unit 1 may affect the operation of input from the default unit '*' - are you sure you want to do this?
C:\Users\steva\Desktop\SHSDRYING.F95(48) : warning 868 - Opening unit 2 may affect the operation of output to the default unit '*' - are you sure you want to do this?
C:\Users\steva\Desktop\SHSDRYING.F95(116) : warning 792 - Comma missing in format
C:\Users\steva\Desktop\SHSDRYING.F95(116) : warning 792 - Comma missing in format
C:\Users\steva\Desktop\SHSDRYING.F95(116) : error 270 - Missing width count for 'G' descriptor
C:\Users\steva\Desktop\SHSDRYING.F95(116) : warning 792 - Comma missing in format
C:\Users\steva\Desktop\SHSDRYING.F95(116) : error 274 - Unknown edit descriptor '(', or missing comma
C:\Users\steva\Desktop\SHSDRYING.F95(292) : warning 868 - Closing unit 1 may affect the operation of input from the default unit '*' - are you sure you want to do this?
C:\Users\steva\Desktop\SHSDRYING.F95(293) : warning 868 - Closing unit 2 may affect the operation of output to the default unit '*' - are you sure you want to do this?
C:\Users\steva\Desktop\SHSDRYING.F95(103) : error 90 - FORMAT label 100 does not exist
Compilation failed.
Unit 5,6 and 1,2 (and others) are reserved... If you make UNIT=1 become UNIT=21 and UNIT=2 become UNIT=22 it will work.
Better is probably to use NEWUNIT
! PROGRAM TO SOLVE DEEP-BED DRYING MODEL
!
! BASIC STATEMENTS
!
PROGRAM DEEP_BED_DRYING !New
IMPLICIT NONE !New
CHARACTER*20 FiIe1, File2
COMMON AMo
COMMON /DENS/ Pmo, Pme
COMMON /THICK/ dxo, Dxe
...
OPEN (NEWUNIT=MyUnit1, FILE=File1) !New
WRITE(*,*)' Unit1=',MyUnit1 !New
...
OPEN (NEWUNIT=MyUnit2, FILE=File2) !New
WRITE(*,*)' Unit2=',MyUnit2 !New
enter code here
!WRITE(1,*) ...
WRITE(MyUnit1,*) ...
IMPLICIT NONE is not a bad habit to get into using.
I would line up things for ease of reading...
WRITE (1, *) 'Mass of sample:' , Wo , ' g'
WRITE (1, *) 'Initial moisture content:' , AMo , ' kg/kg'
WRITE (1, *) 'Depth of sample bed:' , Xo , 'mm'
WRITE (1, *) 'Number of layers in sample bed:' , Nx
WRITE (1, *) 'Steam temperature at inlet' , Tso , 'deg C'
WRITE (1, *) 'Steam flow rate at inlet' , Gso , 'kg/m2s'
WRITE (1, *) 'Expected drying time' , Timeo , ' min'
WRITE (1, *) 'Time interval:' , Dt , ' min'
You either need to compile with -132 or use line continuation...
.F77 or -fixed compiler switch (Anything n Column #6):
WRITE(2, 100)
100 FORMAT(4H J, 9H T(min), 8H M(db),7H Gs , 10H Ts(C) ,
!234567
& 9H Front1, 5H L1, 9H Front2, 5h L2, 9H Depth)
.F90 or -free compiler switch (& at the end):
WRITE(2, 100) !Here
100 FORMAT(4H J, 9H T(min), 8H M(db),7H Gs , 10H Ts(C) , &
!234567
9H Front1, 5H L1, 9H Front2, 5h L2, 9H Depth)
The FORMAT statements in the program use Hollerith edit descriptors, which was a feature deleted from the language as of Fortran 95. These are notoriously error prone - character string edit descriptors should be used instead.
Hollerith edit descriptors are of the form nHxxx - where n characters following the H are equivalent to a character literal. The problem with the identified statement (at least) is that the parenthesis that is meant to close the format statement is being considered part of the literal - probably because a space or similar has been deleted from the source.
100 FORMAT(...9H Depth)
123456789
The error messages also identify that the variable named File1 is not suitable as a FILE= specifier in an open statement. This is because there is no variable declaration for File1, so it is assumed to be of type REAL. There is a declaration for a variable FiIe1. IMPLICIT NONE helps find these sorts of spelling mistakes, but the code has clearly been written using implicit typing.
These sorts of errors suggest that the source has come from optical character recognition or similar. If so, you will need to be very mindful of OCR errors elsewhere in the source.

data entrance error Fortran

I'm learning how to programming with fortran90 and i need receive data from a txt file by the command prompt (something like that:
program.exe"<"data.txt).
at the Input txt file I'll always have a single line with at least 6 numbers till infinity.
if the data was wrote line by line it runs fine but as single line I'm receiving the error: "traceback:not available,compile with - ftrace=frame or - ftrace=full fortran runtime error:end file"
*note: i'm using Force fortran 2.0
here is example of data:
0 1 0.001 5 3 1 0 -9 3
edit: just clarifying: the code is working fine itself except for the read statement, which is a simple "read*,". I want know how To read a entire line from a txt once the entrance will be made by the promt command with stream direction.
( you can see more about that here: https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true).
there is no need to read the code, i've posted it just for knowledge.
I'm sorry about the whole inconvenience.
here is the code so far:
program bissecao
implicit none
integer::cont,int,e,k,intc,t1,t2,t3
doubleprecision::ii,is,pre,prec,erro,somaa,somab,xn
doubleprecision,dimension(:),allocatable::co
t1=0
t2=0
t3=0
! print*,"insira um limite inf da funcao"
read*,ii
!print*,"insira o limite superior da func"
read*,is
! print*,"insira a precisÆo admissivel"
read*,pre
if (erro<=0) then !elimina criterio de parada negativo ou zero
Print*,"erro"
go to 100
end if
!print*,"insira a qtd iteracoes admissiveis"
read*,int
!print*,"insira o grau da f(x)"
read*,e
if (e<=0) then ! elimina expoente negativo
e=(e**2)**(0.5)
end if
allocate(co(e+1))
!print*, "insira os coeficientes na ordem:&
! &c1x^n+...+(cn-1)x^1+cnx^0"
read(*,*)(co(k),k=e+1,1,-1)
somab=2*pre
intc=0
do while (intc<int.and.(somab**2)**0.5>pre.and.((is-ii)**2)**0.5>pre)
somab=0
somaa=0
xn =(ii+is)/2
do k=1,e+1,1
if (ii /=0) then
somaa=ii**(k-1)*co(k)+somaa
else
somaa=co(1)
end if
! print*,"somaa",k,"=",somaa
end do
do k=1,(e+1),1
if (xn/=0) then
somab=xn**(k-1)*co(k)+somab
else
somab=co(1)
end if
!print*,"somab",k,"=",somab
end do
if ((somaa*somab)<0) then
is=xn
else if((somaa*somab)>0)then
ii=xn
else if ((somaa*somab)==0) then
xn=(ii+is)/2
go to 100
end if
intc =intc+1
prec=is-ii
if ((((is-ii)**2)**.5)< pre) then
t3=1
end if
if (((somab**2)**.5)< pre) then
t2=1.
end if
if (intc>=int) then
t1=1
end if
end do
somab=0
xn=(ii+is)/2
do k=1,(e+1),1
if (xn/=0) then
somab=xn**(k-1)*co(k)+somab
else
somab=co(1)
end if
end do
100 write(*,'(A,F20.15,A,F20.15,A,A,F20.15,A,F20.15,A,I2)'),"I:[",ii,",",is,"]","raiz:",xn,"Fraiz:",somab,"Iteracoes:",intc
end program !----------------------------------------------------------------------------
In your program, you are using the "list-directed input" (i.e., read *, or read(*,*))
read *, ii
read *, is
read *, pre
read *, int
read *, e
read *, ( co( k ), k = e+1, 1, -1 )
which means that the program goes to the next line of the data file after each read statement (by neglecting any remaining data in the same line). So, the program works if the data file (say "multi.dat") consists of separate lines (as suggested by OP):
0
1
0.001
5
3
1 0 -9 3
But now you are trying to read an input file containing only a single line (say "single.dat")
0 1 0.001 5 3 1 0 -9 3
In this case, we need to read all the values with a single read statement (if list-directed input is to be used).
A subtle point here is that the range of array co depends on e, which also needs to be read by the same read statement. A workaround might be to just pre-allocate co with a sufficiently large number of elements (say 100) and read the data in a single line, e.g.,
integer :: k
allocate( co( 100 ) )
read *, ii, is, pre, int, e, ( co( k ), k = e+1, 1, -1 )
For completeness, here is a test program where you can choose method = 1 or 2 to read "multi.dat" or "single.dat".
program main
implicit none
integer :: int, e, k, method
double precision :: ii, is, pre
double precision, allocatable :: co(:)
allocate( co( 1000 ) )
method = 1 !! 1:multi-line-data, 2:single-line-data
if ( method == 1 ) then
call system( "cat multi.dat" )
read*, ii
read*, is
read*, pre
read*, int
read*, e
read*, ( co( k ), k = e+1, 1, -1 )
else
call system( "cat single.dat" )
read*, ii, is, pre, int, e, ( co( k ), k = e+1, 1, -1 )
endif
print *, "Input data obtained:"
print *, "ii = ", ii
print *, "is = ", is
print *, "pre = ", pre
print *, "int = ", int
print *, "e = ", e
do k = 1, e+1
print *, "co(", k, ") = ", co( k )
enddo
end program
You can pass the input file from standard input as
./a.out < multi.dat (for method=1)
./a.out < single.dat (for method=2)
Please note that "multi.dat" can also be read directly by using "<".

How to read a mixed text file and extract numbers only

I need to read the output of one of my simulators and store the values. the file name is forces.dat and contains a similar thing as the following:
# Forces
# CofR : (4.750000e-01 3.500000e-02 2.000000e-02)
# Time forces(pressure viscous porous) moment(pressure viscous porous)
2.633022e-02 ((6.268858e-02 -1.468850e+01 1.542745e-20) (1.000906e-03 8.405854e-06 -5.657665e-17) (0.000000e+00 0.000000e+00 0.000000e+00)) ((-8.779466e-18 8.442993e-19 -3.225599e-03) (-2.082489e-18 4.435609e-18 -1.572485e-03) (0.000000e+00 0.000000e+00 0.000000e+00))
8.095238e-02 ((1.781333e-01 -1.468455e+01 -3.545427e-19) (2.362118e-03 2.014609e-05 1.691584e-16) (0.000000e+00 0.000000e+00 0.000000e+00)) ((-3.344781e-18 -5.448339e-19 2.227502e-02) (5.092628e-18 -3.538718e-18 -1.203074e-03) (0.000000e+00 0.000000e+00 0.000000e+00))
1.600000e-01 ((3.204471e-01 -1.467482e+01 -4.599174e-18) (6.936764e-03 1.303800e-04 4.836650e-17) (0.000000e+00 0.000000e+00 0.000000e+00)) ((-1.123589e-17 -4.344967e-19 5.591623e-02) (1.532415e-18 -1.345592e-18 -9.550750e-04) (0.000000e+00 0.000000e+00 0.000000e+00))
I want to know how should I write a Fortran subroutine to ignore the first 3 lines and then read the number of next lines and then the values of each line.
You can use this snippet which will keep a track of line numbers. Based on your requirement and nature of file, you can get the values of respective lines and can do the required.
string CurrentLine;
int LastLineNumber;
void NextLine()
{
// using will make sure the file is closed
using(System.IO.StreamReader file = new System.IO.StreamReader ("c:\\forces.dat"))
{
// Skip lines
for (int i=0;i<LastLineNumber;++i)
file.ReadLine();
// Store your line
CurrentLine = file.ReadLine();
LastLineNumber++;
}
}
In the above code, inside for loop you can put in your logic of file processing based on the lines you want to read.
Although I think it is easier to preprocess the file by some command-line tool (e.g. sed -e 's/(/ /g' -e 's/)/ /g' input.dat), we can also use Fortran directly by reading each line into a long character string and removing all the unnecessary parentheses:
program main
implicit none
integer, parameter :: mxline = 5000 !! choose appropriately
integer i, ios, finp, nl
character(500) str
real, save :: time( mxline )
real, dimension( 3, mxline ), save :: &
frc_pres, frc_visc, frc_poro, &
mom_pres, mom_visc, mom_poro
finp = 10
open( finp, file="input.dat", status="old" )
nl = 0
do
read( finp, "(a)", iostat=ios ) str
if ( ios /= 0 ) exit
str = trim( adjustL( str ) )
!! Skip comment or blank lines.
if ( str(1:1) == "#" .or. str == "" ) cycle
!! Replace parentheses with space.
do i = 1, len_trim( str )
if ( str(i:i) == "(" .or. str(i:i) == ")" ) str(i:i) = " "
enddo
!! Read data from the string.
nl = nl + 1
read( str, * ) time( nl ), &
frc_pres( :, nl ), frc_visc( :, nl ), frc_poro( :, nl ), &
mom_pres( :, nl ), mom_visc( :, nl ), mom_poro( :, nl )
enddo
close( finp )
!! Check.
do i = 1, nl
print *
print *, "time = ", time( i )
print *, "frc_pres = ", frc_pres( :, i )
print *, "frc_visc = ", frc_visc( :, i )
print *, "frc_poro = ", frc_poro( :, i )
print *, "mom_pres = ", mom_pres( :, i )
print *, "mom_visc = ", mom_visc( :, i )
print *, "mom_poro = ", mom_poro( :, i )
enddo
end program
If the data values can become very large (say, 1.0e100), please consider using double-precision reals so as not to loose necessary precision.

Gnuplot - Plot in one graph multiple files

I am programming in bash and I try to make a graph out of 4 files using gnuplot.
My files contain in the first column the date and in the rest 10 columns the temperature of the ocean in various depths. I get the errors, line 0: invalid command and line 0: constant expression required.
MyVar="THO"
MySeas="Annual Win Spr Aut Sum"
MyWorkDir=/work/InterAnnual
echo "change dir"
cd $MyWorkDir
MyFileArx1=0001_field_${MyVar}.grb.regular
MyFileArx21=0021_field_${MyVar}.grb.regular
MyFileArx25=0025_field_${MyVar}.grb.regular
MyFileArx26=0026_field_${MyVar}.grb.regular
for MySeasName in ${MySeas} ;do
MyFile1=${MyFileArx1}_sm_${MySeasName}.col.dat
MyFile21=${MyFileArx21}_sm_${MySeasName}.col.dat
MyFile25=${MyFileArx25}_sm_${MySeasName}.col.dat
MyFile26=${MyFileArx26}_sm_${MySeasName}.col.dat
gnuplot << EOF
set term postscript eps enhanced color solid
set out 'InterAnnual.${MySeasName}.6.eps'
set key right top
set grid
set xrange [ 800:2000 ]
set size 1, 0.5
set xlabel "year"
set ylabel " T (C) "
plot "${MyFile1}" u 1:11 t 'Level-6 ${MySeasName} mil0001' w l lt, \
"${MyFile21}" u 1:11 t 'Level-6 ${MySeasName} mil0001' w l lt, \
"${MyFile25}" u 1:11 t 'Level-6 ${MySeasName} mil0001' w l lt, \
"${MyFile26}" u 1:11 t 'Level-6 ${MySeasName} mil0001' w l lt
EOF
done
`
The script works when I add in the gnuplot part: set multiplot.
For example:
gnuplot << EOF
set multiplot
... and then the rest of the lines.