- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am working on a solver that has a large number of input parameters that I would like to load from a file. One issue I though I would have is that the size of some arrays are defined by said input.
Eventually my program solves some distribution function (some n_x by n_v matrix) that I would like to save to a file as well.
Any ideas whats the best to do that on the Windows compiler?
example code
program test_1
implicit none
real , parameter :: alpha=1
integer , parameter :: n_x=10
integer , parameter :: n_v=10
real,dimension(n_x,n_v) :: f
integer :: i, j
do i=1,n_x
do j =1,n_v
f(i,j)= i*j
end do
end do
end program
Here is where I want to save f to an external file for some farther analysis.
Thanks!
Best,
Erez
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer :: nx, ny, mystat real, dimension(:,:), allocatable :: f .. open(11,file='my.dat',status='old') read(11,*)nx,ny close(11) ! check if nx and ny are reasonable allocate(f(nx,ny,status=mystat) ! check if allocation succeeded ! do calculations open(12,file='my.res',status='replace') write(12)nx,ny,f close(12)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just one comment to clarify a little something (for others who may not realise).
Because n_x and n_v are "parameters" they are compile time constants and not variables, so their value cannot be changed during program execution.
If the values need to be set at run time then they need to be variables. First read the file containing these values, allocate the arrays as necessary, and proceed with the computation.
That way problems of different size can be run by using different input files and no need to recompile the program.
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Erez,
in case there is more than one matrix or multiple input data (control, output, plot, etc.), I think a container format such as XML, JSON (Fortran Interface e.g. https://github.com/jacobwilliams/json-fortran), HDF5 or whatever could be helpful and make it more user friendly and flexible. If you just need a very small amount of data a self made structure would do it.
A simple version I prefer:
# some comment *my_data_type_keyword { 0.1 0.2 0.3 0.4 } # second data entry *my_2nd_data_type_keyword 42 # *my_output_file 'control.log'
With some little parsing you can also avoid to give explicitly the matrix dimensions. Non-matching matrix dimensions normally generates ugly errors...
Johannes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the great replay guys,
One quick questions.
If I use the method described in the first reply, do I simply need to put the input file 11 (this is simply a text file right?) in the same folder as my solution?
Also, I simply need to put the value for each variable in a different line in that file right? As such
content of file 11.text (for two variables)
30
40
end of file
Also, the Fortran solution will make me a new file with my results right? (12.text) I wouldn't need to make a file in the folder with that name?
Last question, I will need to save my matrix f through the calculation as well. I am interested in how it evolves as well as its final state. Would a text file be a good way to do this? or is there a better format? I want to take it to MATLAB for plotting later.
Thanks,
Erez
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Erez,
I would look into the documentation for I/O with Fortran. The help for write contains some more examples and show how to write 'formatted' ASCII or binary files. The latter would be an option for intermediate big files, Matlab can read Fortran binary data files. Fixed units (11) should not be used anymore, since newunit is an elegant alternative IMHO.
You can also work with sub-folders etc. (e.g. changedirqq or by giving the path in the file statement in the open command).
Regards, Johannes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Erez,
The values don't have to be on separate lines. With an appropriate format on the READ statement you can read several values at one go.
As regards the output file: it depends on what your program does.
You should look at the help on OPEN, READ, WRITE and FORMAT (the Fortran I/O) statements as Johannes suggests.
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Erez K. wrote:
.. If I use the method described in the first reply, do I simply need to put the input file 11 (this is simply a text file right?) in the same folder as my solution? .. Last question, I will need to save my matrix f through the calculation as well. I am interested in how it evolves as well as its final state. Would a text file be a good way to do this? or is there a better format? I want to take it to MATLAB for plotting later. ..
@Erez,
Perhaps it will be helpful if you can provide some background about yourself, what are you to trying to do, and how far you want to "take it" as far "software engineering" for your work is concerned. On one hand, you're asking very basic questions which are well-covered in many Fortran sources including books, on the other hand it's unclear you're even making use of material readily available at your fingertips such as Intel Fortran User and Reference Guide, but then there is need for systems integration such as making use of MATLAB which can be quite simple for those "in the know" but for some who don't "read up by themselves", it can be umpteen posts on online forums all over. Given the lack of clarity of your situation, suggestions such as using JSON and XML may just the right thing you need or they may be "a sledgehammer to crack a nut".
Say your need is to do fairly simple stuff that invidiual coders often do (as opposed to a team of professional developers building some big, software) and you seek a Fortran-only situation. In that case, look into Fortran standard NAMELIST feature: https://software.intel.com/en-us/node/580891
Per your original post, you indicate simulation parameters such as n_x and n_y and simulation data such as f. In that event, you might find it easy to create an input file for your calculations in human-readable and understandable format such as this:
&sim_params n_x=2, n_y=3, / &sim_data f=1.0,2.0,3.0,4.0,5.0,6.0, /
You can create a Fortran program, say mysim.exe, and run it with standard Windows command prompt action such as mysim xxx\in.txt yyy\out.txt where xxx is the folder path for your input file and yyy is the folder path for your simulation output. This addresses your other question of where the files need be located; they can be anywhere, as long the location is accessible to the Fortran program. Example code to do so is given below, hopefully it is self-explanatory.
module m implicit none private !.. "Simulation" parameters integer :: n_x = 0 integer :: n_y = 0 !.. "Simulation" data real, allocatable :: f(:,:) !.. I/O variables namelist /sim_params/ n_x, n_y namelist /sim_data/ f logical :: FileExists integer :: FileUnit character(len=256) :: msg !.. Public methods public :: ReadData public :: RunSimulation public :: WriteData contains subroutine ReadData( FileName, ErrorCode, ErrorMessage ) !.. Argument List character(len=*), intent(in) :: FileName integer, intent(inout) :: ErrorCode character(len=*), intent(inout) :: ErrorMessage !.. Local variables integer :: I !.. ErrorCode = 0 ErrorMessage = "" inquire( file=FileName, exist=FileExists) if ( FileExists ) then open( newunit=FileUnit, file=FileName, status="old", iostat=ErrorCode, iomsg=msg ) if ( ErrorCode /= 0 ) then !.. Error handling elided ErrorMessage = msg return end if read( unit=FileUnit, nml=sim_params, iostat=ErrorCode, iomsg=msg ) if ( ErrorCode /= 0 ) then !.. Error handling elided ErrorMessage = msg return end if if ( (n_x <= 0).or.(n_y <=0 ) ) then !.. Invalid data; error handling elided msg = "Invalid values for n_x/n_y in input file." ErrorCode = 2 return end if !.. Proper action elided; here the "simulation data" is allocated f = reshape( source=[( 0.0, I=1,n_x*n_y)], shape=[ n_x, n_y ] ) !.. Then read the data in from the file read( unit=FileUnit, nml=sim_data, iostat=ErrorCode, iomsg=msg ) if ( ErrorCode /= 0 ) then !.. Error handling elided ErrorMessage = msg return end if else !.. Error handling elided ErrorCode = 1 msg = "Input file cannot be found." ErrorMessage = msg return end if !.. return end subroutine ReadData subroutine RunSimulation( ErrorCode, ErrorMessage ) !.. Argument List integer, intent(inout) :: ErrorCode character(len=*), intent(inout) :: ErrorMessage !.. Local variables !.. ErrorCode = 0 ErrorMessage = "" !.. Proper action elided; here the action is simply to add 42 to existing data! f = f + 42.0 !.. return end subroutine RunSimulation subroutine WriteData( FileName, ErrorCode, ErrorMessage ) !.. Argument List character(len=*), intent(in) :: FileName integer, intent(inout) :: ErrorCode character(len=*), intent(inout) :: ErrorMessage !.. Local variables !.. ErrorCode = 0 ErrorMessage = "" !.. Appropriate action elided; here any existing file is overwritten open( newunit=FileUnit, file=FileName, status="replace", iostat=ErrorCode, iomsg=msg ) if ( ErrorCode /= 0 ) then !.. Error handling elided ErrorMessage = msg return end if !.. Add "simulation parameters" to file in NAMELIST format write( unit=FileUnit, nml=sim_params, iostat=ErrorCode, iomsg=msg ) if ( ErrorCode /= 0 ) then !.. Error handling elided ErrorMessage = msg return end if !.. Add "simulation data" to file in NAMELIST format write( unit=FileUnit, nml=sim_data, iostat=ErrorCode, iomsg=msg ) if ( ErrorCode /= 0 ) then !.. Error handling elided ErrorMessage = msg return end if !.. return end subroutine WriteData end module m
program p use, intrinsic :: iso_fortran_env, only : output_unit use m, only : ReadData, RunSimulation, WriteData implicit none integer :: irc integer :: leni integer :: leno integer :: numargs character(len=2048) :: errtxt character(len=256) :: InputFile character(len=256) :: OutputFile NumArgs = command_argument_count() if ( NumArgs > 0) then call get_command_argument(1, InputFile, leni, irc) if (irc /= 0) then write( unit=output_unit, fmt='(*(g0))' ) "Error processing first argument." stop end if if (numargs > 1) then call get_command_argument(2, OutputFile, leno, irc) if (irc /= 0) then write( unit=output_unit, fmt='(*(g0))' ) "Error processing first argument." stop end if end if end if call ReadData( FileName=InputFile, ErrorCode=irc, ErrorMessage=errtxt ) if (irc /= 0) then write( unit=output_unit, fmt='(*(g0))' ) "ReadData failed: ", trim(errtxt) stop end if call RunSimulation( ErrorCode=irc, ErrorMessage=errtxt ) if (irc /= 0) then write( unit=output_unit, fmt='(*(g0))' ) "RunSimulation failed: ", trim(errtxt) stop end if call WriteData( FileName=OutputFile, ErrorCode=irc, ErrorMessage=errtxt ) if (irc /= 0) then write( unit=output_unit, fmt='(*(g0))' ) "WriteData failed: ", trim(errtxt) stop end if stop end program
Upon execution with Intel Fortran, the above code creates an output:
&SIM_PARAMS N_X = 2, N_Y = 3 / &SIM_DATA F = 43.00000 , 44.00000 , 45.00000 , 46.00000 , 47.00000 , 48.00000 /
The above output can now be read back by the Fortran program since it is in a supported format. Also, by encapsulating the "ReadData" procedure suitably and which is then invoked by MATLAB, the data can be loaded into MATLAB as well.
Clearly the above is but one simple "standard" and all Fortran solution; some may call it a "poor man" approach. For more extensive and/or sophisticated needs, other approaches can be used including JSON, XML, etc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:
@Erez,
Perhaps it will be helpful if you can provide some background about yourself, what are you to trying to do, and how far you want to "take it" as far "software engineering" for your work is concerned. On one hand, you're asking very basic questions which are well-covered in many Fortran sources including books, on the other hand it's unclear you're even making use of material readily available at your fingertips such as Intel Fortran User and Reference Guide, but then there is need for systems integration such as making use of MATLAB which can be quite simple for those "in the know" but for some who don't "read up by themselves", it can be umpteen posts on online forums all over. Given the lack of clarity of your situation, suggestions such as using JSON and XML may just the right thing you need or they may be "a sledgehammer to crack a nut".
Say your need is to do fairly simple stuff that invidiual coders often do (as opposed to a team of professional developers building some big, software) and you seek a Fortran-only situation. In that case, look into Fortran standard NAMELIST feature: https://software.intel.com/en-us/node/580891
Per your original post, you indicate simulation parameters such as n_x and n_y and simulation data such as f. In that event, you might find it easy to create an input file for your calculations in human-readable and understandable format such as this:
Hey, I am an undergraduate physics major working on a research project. I am moving a code I collaborated on from MATLAB to Fortran to decrease the computational time. I am a beginner/novice in MATLAB but I have never really coded, lucky the code is not to complicated.
The program is designed to solve a PDE, specifically the Vlasov-Poisson set of equations. The evolving function is some density distribution function with a known inital shape.
I have a code which compiles, and I would like to input data to it (without compiling each time) and save a file with the 100 "pictures" of the time evolution of the distribution function. The code is about 300 lines. Thanks for all the tips. I will try to implement them.
I hope this explanation is sufficient and your efforts could be focused.
Appreciate all the helpful replays and remarks.
Best,
ERez
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Erez K. wrote:
.. I am an undergraduate physics major working on a research project. ..
So are you a student now? Or recently where one? Assuming as such and depending on your immediate and long-term goals, you may want to consider following a more structured approach toward picking up Fortran, one that a current or a recent student will be used to, by reviewing closely the books mentioned in this Dr Fortran blog https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan,
I am a current student, graduating in a month or so. I am working on this solver for my senior TheSis.
I am interested in "diving" deeper into Fortran in the coming year but at this specific moment in time I just want to make this project work.
Best,
Erez
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page