I can't understand why my Fortran90 program does not write to file anymore. It used to work some hours ago. I haven't modified that part of the code, nor I have introduced some conditions by virtue of which it should not write to file . On the next line i have put a print command which writes on terminal the same values that should be written to file, and this works.
open(500, file='data.dat')
write(500,fmt='(E14.4,E14.4)') A,B !this SHOULD be printed on unit 500
write(*, fmt='(E14.4,E14.4)') A,B ! this is printed on terminal
I have tried to change unit, but nothing changes. I have tried to open a new file with a new name and writing onto it, also in other parts of the code, even at the beginning, just after variables declaration. This does not seem to work either. It is so frustrating, because everything worked properly previously. What could have happened?
Using gfortran 5.3 under Linux and the following program (that is your code copy-pasted and the minimal boilerplate).
program hop
implicit none
double precision :: A, B
A = 1
B = 2
open(500, file='data.dat')
write(500,fmt='(E14.4,E14.4)') A,B !this SHOULD be printed on unit 500
write(*, fmt='(E14.4,E14.4)') A,B ! this is printed on terminal
end program hop
outputs 0.1000E+01 0.2000E+01 in the terminal and the exact same content in the file data.dat.
Is the write instruction in a program that hangs? Not seeing output might be related to i/o buffering.
Is the behaviour changing if you add the line
flush(500)
after the write instruction?
I have to write to file in a cycle. Now I open the file in the cycle having added position='append' and I close it at the end of the cycle. Just like
program pro
implicit none
integer (kind=2) :: i, A, B
do i=1,10
A=i
b=i+1
open(500, file='file.dat', position='append')
write(500, *) A, B
close(500)
enddo
That seems to work now.
Related
I am making user subroutine file of Abaqus.
However, in reading a file I met with a difficulty.
Since, it is Fortran 77 based, it is so hard to find exact solution.
My intention is to read a file where an 1X1 array is include. Then, to find an index of a value in the array.
My code to read a file is :
open (unit=99,file='D:\SIMULATION\dist.txt',status='old')
read (99,*) dist
close (99)
And the code for finding index of value in array is:
loc=minloc(abs(dist-1),1)
I think minloc is for Fortran 90, right?
Is there any function in Fortran 77 similar to minloc?
The code you've shown should compile and run as expected. I'm assuming that you are actually reading a 1xN array and that when you said "1X1" it was a typo - otherwise, there's no point in using minloc.
However, the error message you reported in a comment (An array-valued argument is required in this context) only occurs if you use the minloc intrinsic on a scalar value. Thus, my guess is that you did not declare dist as an array. Here is a quick example of what I mean:
! The contents of 'values.txt' are: -3.1, 4.1, 5.9, 2.6, -5.4
! Values may be separated by commas or blanks.
program get_min_dist
implicit none
real :: x ! <-- Cannot be used to represent an array.
real, dimension(5) :: a ! <-- An array of 5 reals. Do this instead.
integer :: loc, funit1
open(newunit=funit1, file="values.txt", status="old")
read(funit1,*) x
rewind(funit1)
read(funit1,*) a
close(funit1)
loc = minloc(abs(a-1),1) ! <-- I'm assuming there is a reason to
! subtract 1 from all values in the array
! loc = minloc(abs(x-1),1) ! <-- Error 'An array-valued arg is required`
print*, "x=",x
print*, "a=",a
print*, "index=", loc
print*, "value=", a(loc)
end program get_min_dist
With read(funit1,*) x the first value will be assigned when the file is read, resulting in the error message you have seen. With the array a, however, you get the expected output.
Your confusion regarding the need to use F77 compatible code may be due to the fact that Abaqus continues to provide examples and docs with F77-style fixed-formatting, and requires Fortran source code to be given the .f or .for extension1. By default, this extension tells ifort to expect fixed-format code2. However, any Fortran features supported by the version of the compiler you use is still valid - even in fixed-format, if you must. For further information about the availability of features from different Fortran versions, see your (Intel Fortran) documentation.
1 I'd be glad to know if this can be changed somehow, e.g. to allow the .f90 extension.
2 This setting can be changed in the Abaqus environment file, at least for the versions I've used (6.9-6.14). I don't think that has changed with newer releases, but maybe. I don't recommend changing it if you share the environment with other users without their consent, especially for newbies.
I have a module with a function which takes a starting and ending point and reads in a .txt some float value.
I wish that function to return a table which I do not know how large it will be before it starts.
I wish to use this function twice in the main program to make a third real array. But Fortran doesn't like it much.
Here is my code for the function :
module ReadData
!in this part, you need to know :
! -the starting (cannot be the first or second point)
! -end point
! -the file name (here : cham/comp or flow)
! change line 40 in case it is not AL026_Pd anymore
! -where it is on the file
implicit none
INTERFACE ReadP
MODULE PROCEDURE ReadDataPressure
END INTERFACE
private :: ReadDataPressure
contains
function ReadDataPressure (whereabout,StartingPoint,EndingPoint) result (P1)
!**********************
!**decla in variables**
character(50) :: whereabout !needed : cham/comp or flow
real(8) :: StartingPoint,EndingPoint
!************************
!**decla used variables**
character(50) :: FileNameConstructed
real(8) :: deltat,CurrentTime,pressure
integer(8) :: i,k
!**********************
!**decla out variable**
real(8),allocatable :: P1(:)
!start of the programe itself
write (FileNameConstructed,'(a,a,a)') "AL026_pd",whereabout,".txt"
open(20,file=FileNameConstructed,status='old',action='read')
read (20,*) deltat,pressure
read (20,*) CurrentTime,pressure
deltat=CurrentTime-deltat
!now deltaT is the loop counter, but we "lost" two usable line in the process
allocate (P1(1:int(((EndingPoint-StartingPoint)/deltat+1))))
k=1
do i=0,int((EndingPoint-2*deltat)/deltat)
read (20,*) CurrentTime,pressure
if (CurrentTime>StartingPoint) then
P1(k)=pressure
k=k+1
write(*,*) p1(k)
end if
end do
end function ReadDataPressure
End module
and I wish to do something like this in the main program
a=ReadP(comp,350,750)
b=ReadP(flow,350,750)
do i=1; lenght_of_a
m_ox(i)=squarreroot(a(i)-b(i))
end do
end then write it in another file.
I found : Share allocatable Arrays
FORTRAN - allocatable array in subroutine
but they did not help me.
One thinks perhaps
http://www.stanford.edu/class/me200c/tutorial_90/09_modules.html
is closer to the solution.
But they don't want a table at the end, they use Prod_A = PRODUCT(A) so you do not know the dimension of a, but can do product or sum. But I want to keep it whole.
In the main program you should be able to declare an allocatable array A and, if you have a Fortran 2003 compiler, do:
A = ReadDataPressure
Which is what you wish. This is allocation on assignment, which is part of Fortran 2003.
Why do you say that "fortran doesn't like it"? What are the specific error messages?
With compilers that don't support this it will be easier though less elegant to make the procedure a subroutine. Declare the array as allocatable in both the main program and the subroutine. Make it an intent (out) argument and allocate it in the subroutine.
P.S. Unless there are other aspects that you are not showing, setting up a module procedure for a single procedure seems pointless. I would leave off the interface and module procedure and make ReadDataPressure public so that it is directly called.
the mistake was :
character(50) :: whereabout
because there was
write (FileNameConstructed,'(a,a,a)') "AL026_pd",whereabout,".txt"
except that FileNameConstructed is also a character(50). (So i try to fit a 8+50+4 into 50).
But I was not able to see it before removing the private.
So thank MSB. You helped me a lot. I change whereabout in character(4) (since it feet my need perfectly) and so it is running
I am trying to write in two different places (the main program and a subroutine) unformatted files in my Fortran code. The problem is that when I do it, the results change and I suspect that it is because the memory assignment is overwriting the data that I am using to make the simulation in my CFD code. I ask: Is it possible that one can just use the unformatted file (to write) once in the code? I mean, I have to use the same file to save all my data and not with different files.
I copy and past the two parts of the code to show what I am want to describe:
In the main program, the loop is:
call numcar (isave,suffix)
longueur=index(nchamp,' ')-1
nfichier=nchamp(1:longueur)//suffix
longueur=index(nfichier,' ')-1
open(10,file=nfichier(1:longueur),form='unformatted')
write(10) real(uxn,4),real(uyn,4),real(wzn,4),real(ppo,4)
close(10)
! *****************************************
isave=isave+1
and in the subroutine, the loop is:
call numcar (isavediv,suffix1)
longueur1=index(ndiv,' ')-1
nfichier1=ndiv(1:longueur1)//suffix1
longueur1=index(nfichier1,' ')-1
open(20,file=nfichier1(1:longueur1),form='unformatted')
write(20) real(ppm,4)
close(20)
! *****************************************
isavediv=isavediv+1
All the variables all declared as IMPLICIT NONE in both main program and subroutine.
I solved my problem.
The problem was that I was using the channel number 20 and a colleague of mine told me that this channel is used by the computer or some devices to process data.
I changed it for channel number 10 and it worked good again.
Thank you for your comments.
Now it looks so:
open(10,file=nfichier1(1:longueur1),form='unformatted')
write(10) real(ppm,4)
close(10)
I am calling an R function from the R package e1071 which is interfaced with libsvm (a C program). This function is passing C (printf) warning messages to the R console. I know this because the warning messages are of the form (warning:...) whereas R warning messages are capitalized (i.e. Warning:...).
I've tried everything to get rid of these messages in R (sink, suppressWarnings, invisible) but nothing seems to work.
Any ideas?
Thanks!
The function uses stdio instead of Rprintf/REprintf or warning which is why re-direction of the R output won't work. The proper solution is to fix the calls in libsvm to use R output instead.
Hacking the stdio output is possible - you can re-direct the output to your own pipe and do what you want with it, but a) it's a bit of work in C and b) it's dangerous because you need to restore the standard behavior after you're done with the function - even if it errors out and c) in may interact with R output if used on a shell.
If you want a really whacky, dirty yet quick solution, run your function in collect(parallel(..., silent=TRUE))[[1]] from multicore - it suppresses stdout (you can add multicore:::closeStderr() if you want to suppress stderr as well).
I have written a Matlab GUI for my C program. I thought about using MEX, but there are too many C files and C program requires a DLL to run.
So, instead I have the Matlab System function calling the executable with inputs, something like [status results] = system('executable "input 1" "input 2"'), which runs well, but I want real time output. results is just a percent output of how complete the program is, and I want to use this output for a GUI progress bar in Matlab.
The output does get stored into results, but only after the program is complete. Thus, making the progress bar pointless.
Is it possible to get the executable to send outputs one at a time to Matlab, and then have Matlab update the progress bar, and return to the executable?
Edit: I'm looking for a solution in Windows.
I only see two options, and neither fits directly with your current implementation approach.
The first, is to just use sockets to communicate between the two. Here's a pure matlab socket implementation, but under the hood it's using C sockets. It's been 10 years since I've done C/Java socket comms, but I recall that at the time there were some issues.
http://www.mathworks.com/matlabcentral/fileexchange/21131-tcpip-socket-communications-in-matlab
Another option is to have your executable be accessible via a C DLL from matlab, and call the DLL directly from matlab (i.e. have matlab control your app). This is the way I've been doing most such interactions lately, and it works very well.
http://www.mathworks.com/help/techdoc/ref/loadlibrary.html
I found a solution. Credit goes to Richard Alcock at Matlab Central
Specifically, for my solution:
cmd = {'executable.exe', 'input 1', 'input 2'};
processBuilder = java.lang.ProcessBuilder(cmd);
cmdProcess = processBuilder.start();
% Set up a reader to read the output from the command prompt
reader =
java.io.BufferedReader(...
java.io.InputStreamReader(...
cmdProcess.getInputStream() ...
) ...
);
% Loop until there is some output
nextLine = char( reader.readLine );
while isempty(nextLine)
nextLine = char( reader.readLine );
end
% Then loop until there is no more output
while ~isempty(nextLine);
fprintf('Output: %s\n', nextLine);
nextLine = char( reader.readLine );
end
% Get the exit value of the process
exitValue = cmdProcess.exitValue
Note: this code does not hold up the executable. The executable must finish before this code finishes, otherwise this code crashes when it gets ahead of the executable.