CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > OpenFOAM Programming & Development

Cannot read 2nd column of data in libforces.so output force.dat file

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree1Likes
  • 1 Post By ngj

Reply
 
LinkBack Thread Tools Display Modes
Old   September 1, 2013, 00:39
Default Cannot read 2nd column of data in libforces.so output force.dat file
  #1
Senior Member
 
musaddeque hossein
Join Date: Mar 2009
Posts: 250
Rep Power: 8
musahossein is on a distinguished road
Dear all:

I am using libforces.so in control dict. The output is forces.dat file and has the following format:

time ((number, number, numer), (number ...etc)

the problem is that there is NO spaces between the first pair of parenthesis and the number right after it. As a result, that number cannot be read as a number but has to be read as character. I have a FORTRAN code that reads this file, and I found that it was not possible to read the first number after the double parenthesis as a real. So my only option is to read it as character - which makes this data useless. Can the OpenFOAM creators please rewrite the code so that there is space between the number and the parenthesis?. Also, would it be possible to include the number of lines of data in the file in the first line? something like this:

# Time forces((.....)) moment ((......)) lines of data (......)

Thanks.

Thanks.
musahossein is offline   Reply With Quote

Old   September 1, 2013, 06:57
Default
  #2
Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 6,987
Blog Entries: 32
Rep Power: 69
wyldckat is a jewel in the roughwyldckat is a jewel in the roughwyldckat is a jewel in the rough
Hi Musaddeque,

Why should the developers change the source code, when it works fine as it is? Specially when it is formatted in a way that OpenFOAM itself can easily re-read the data back into memory!
Nonetheless, what you might want to ask for is for a way to choose other output formats for the forces function object.

Either way, there are several ways you can fix this problem on your side! Some examples:
  1. You can pre-process the file with a script, to remove the parenthesis. sed and/or awk can help you with this. The simplest command I can remember is to simply use:
    Code:
    sed -i -e 's/[()]/ /g' forces.dat
    It will convert the parenthesis characters to spaces. You can search online on how to use sed and awk.
  2. In FORTRAN you can easily read the parenthesis characters with CHAR variables, therefore filtering out what you don't want.
  3. OpenFOAM is open-source! You can modify the source code for the forces function object and make it write things as you want it to!
Best regards,
Bruno
wyldckat is offline   Reply With Quote

Old   September 1, 2013, 07:49
Default
  #3
ngj
Senior Member
 
Niels Gjoel Jacobsen
Join Date: Mar 2009
Location: Rotterdam, The Netherlands
Posts: 1,510
Rep Power: 23
ngj will become famous soon enoughngj will become famous soon enough
Hi Musaddeque,

Please read and follow the detailed step-by-step guide, which I wrote a couple of weeks ago in this thread:

Modifying forces.C to output CSV

Kind regards

Niels
wyldckat likes this.
__________________
Please note that I do not use the Friend-feature, so do not be offended, if I do not accept a request.
ngj is offline   Reply With Quote

Old   September 1, 2013, 10:58
Default
  #4
Senior Member
 
musaddeque hossein
Join Date: Mar 2009
Posts: 250
Rep Power: 8
musahossein is on a distinguished road
Quote:
Originally Posted by wyldckat View Post
Hi Musaddeque,

Why should the developers change the source code, when it works fine as it is? Specially when it is formatted in a way that OpenFOAM itself can easily re-read the data back into memory!
Nonetheless, what you might want to ask for is for a way to choose other output formats for the forces function object.

Either way, there are several ways you can fix this problem on your side! Some examples:
  1. You can pre-process the file with a script, to remove the parenthesis. sed and/or awk can help you with this. The simplest command I can remember is to simply use:
    Code:
    sed -i -e 's/[()]/ /g' forces.dat
    It will convert the parenthesis characters to spaces. You can search online on how to use sed and awk.
  2. In FORTRAN you can easily read the parenthesis characters with CHAR variables, therefore filtering out what you don't want.
  3. OpenFOAM is open-source! You can modify the source code for the forces function object and make it write things as you want it to!
Best regards,
Bruno
Gentlemen: appended below are few lines from the forces.dat file.

# Time forces(pressure, viscous, porous) moment(pressure, viscous, porous)
0.00116279 ((0 65.2165 0),(-1.20232e-17 0.00107097 5.21998e-07),(0 0 0)) ((15.435 0 0),(0.000198423 2.02581e-17 8.3249e-17),(0 0 0))
0.00251938 ((0 86.7929 0),(-1.10799e-16 0.00264427 1.61168e-06),(0 0 0)) ((20.5327 0 0),(0.000532886 -2.13627e-17 -1.9528e-16),(0 0 0))
0.00410207 ((0 30.7788 0),(-1.1e-16 0.00314398 4.56226e-06),(0 0 0)) ((7.26688 0 0),(0.000714734 -5.21951e-17 6.56713e-17),(0 0 0))
0.00593798 ((0 -34.7985 0),(-8.21523e-17 0.00205407 -1.62991e-06),(0 0 0)) ((-8.2514 0 0),(0.000595282 -1.95364e-17 -1.90247e-17),(0 0 0))

Now observe the second line:

0.00116279 ((0 65.2165 0), .....

I am using fortran read command as follows:

read(......) time, char, char, forceX, forceY, forceZ etc..

Fortran hangs at char, as it cannot distinguish between the "((" and the "0" right after it and gives an error saying bad real number. So now, if I revise the read statement as:

read(...) time, char, forceY, forceZ, --- in other words treat "((0" as a char, then fortran will read it as char and move the the next number. I agree that scripts can be written to remove the parenthesis, but it does not permit an elegant solution. At the programming time, all the programmer would have had to do was to add a few spaces between the parenthesis, and between the parenthesis and the number.
musahossein is offline   Reply With Quote

Old   September 1, 2013, 13:07
Default
  #5
Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 6,987
Blog Entries: 32
Rep Power: 69
wyldckat is a jewel in the roughwyldckat is a jewel in the roughwyldckat is a jewel in the rough
Hi Musaddeque,

Well... I had to smile a bit now... I remembered to search in the official bug tracker for OpenFOAM and found this feature request: http://www.openfoam.org/mantisbt/view.php?id=777
I found it by searching in Google with:
Code:
site:www.openfoam.org/mantisbt forces output
Therefore, the suggestion you've made has already been made 5.5 months ago as well


Now, as for the problem you have at the moment, the big question is: how do you want to solve this?
I ask this because:
  1. I'm very well experienced in FORTRAN 90 and know a bit the quirks of FORTRAN 77. Therefore, if you are using GNU FORTRAN (the one that comes with GCC) and tell me if you are using F77 or F90, then I can easily create the line of code that handles reading these lines.
  2. It also depends on whether you need to process the forces output, while it's still running, because there are a few possible solutions.
  3. If you prefer to have your own variant of the forces library, it's very simple to explain how you can create your own function object, derived from the original source code.
  4. If you forcefully want the original source code to be modified... then the only way that can happen with greater speed, is to acquire from the official OpenFOAM team a support contract for this particular feature.
Best regards,
Bruno
wyldckat is offline   Reply With Quote

Old   September 2, 2013, 09:08
Default fortran read of force.dat file
  #6
Senior Member
 
musaddeque hossein
Join Date: Mar 2009
Posts: 250
Rep Power: 8
musahossein is on a distinguished road
This is what I wrote to read the lines of data. I am only interested in the x y z forces, so my read line in fortran was as follows:

character(len=20):: charA,
double precision::time, force_x, force_y, force_z

read(unit=unit_force_dat,fmt=*)

do i=1,num_dat

read(unit=unit_force_dat,fmt=*) time, charA, force_y

write(fout_gplt,100) time*3.13029, force_y/9810.0

end do

Now note the data is out put in the following format (skipping the first line):
0.1 ((0 -5.06121 0),(-3.99743e-17 -0.00915985 -0.00028693),(0 0 0)) ((-0.801432 0 0),(-0.0036854 -3.35203e-18 2.30784e-17),(0 0 0))
0.2 ((0 19.0264 0),(1.57733e-17 0.00228343 -0.000354185),(0 0 0)) ((4.92259 0 0),(0.0023383 7.10629e-18 1.67709e-18),(0 0 0))
0.3 ((0 11.5462 0),(-7.85821e-18 0.00388275 -0.000954584),(0 0 0)) ((2.82873 0 0),(0.00702285 -4.54422e-18 -1.1446e-18),(0 0 0))

So starting from the left, there is one real number, followed by space, then two parenthesis and then three real numbers. So my read statement should be:

read (...) time, charA, charB, forceX, forceY, forceZ

But it seems that the real number after the second parenthesis is so close, that fortran gives a "bad real number" error if I use this format. So the "workaround" that I have is to treat the ((0 as char and then read forceY. Perhaps you may have a better suggestion.

Thanks
Musa
musahossein is offline   Reply With Quote

Old   September 7, 2013, 11:02
Default
  #7
Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 6,987
Blog Entries: 32
Rep Power: 69
wyldckat is a jewel in the roughwyldckat is a jewel in the roughwyldckat is a jewel in the rough
Hi Musaddeque,

I forgot that I haven't actually seriously programmed in FORTRAN for several years now... I'm getting old .

Attached is a zip file that demonstrates how you can filter out the stuff you don't need from each line.
Since you didn't specify any compiler limitations, nor did you specify the FOTRAN standard, I simply used the one I'm familiar with.


To detail some of the aspects to this:
  1. I used gfortran that GCC provides, more specifically version 4.6.3.
  2. The FORTRAN file is named "test.f90" and the data file is named "data".
  3. The core reading and writing code:
    Code:
    CHARACTER(LEN=200):: buffer
    DOUBLE PRECISION::time, force_x, force_y, force_z
    INTEGER :: unit_force_dat=10, i, num_dat=3, fout_gplt=20
    
    OPEN(UNIT=unit_force_dat, FILE="data", ACTION="READ", POSITION="REWIND", ACCESS="SEQUENTIAL")
    OPEN(UNIT=fout_gplt, FILE="output.txt", ACTION="WRITE", POSITION="REWIND", ACCESS="SEQUENTIAL")
    
    READ(UNIT=unit_force_dat,FMT=*)
    
    DO i=1, num_dat
    
      READ(UNIT=unit_force_dat, FMT='(A)') buffer
    
      !Filter out the parenthesis and commas
      CALL FilterLine(buffer)
    
      READ(buffer, FMT=*) time, force_x, force_y, force_z
      
      WRITE(fout_gplt, *) time*3.13029, force_y/9810.0
    
    END DO
    
    CLOSE(unit_force_dat)
    CLOSE(fout_gplt)
    1. As you can see, I loaded the whole line into a long character array, to act as a buffer.
    2. Then call the subroutine "FilterLine" to remove the parenthesis and commas.
    3. Then read directly from the cleaned text line that is on the updated buffer.
  4. The subroutine is this one:
    Code:
    SUBROUTINE FilterLine(buffer)
    
        CHARACTER(*), INTENT(IN OUT) :: buffer
        CHARACTER(3) :: junk = "(),"
        INTEGER :: I, N
        
        DO I = 1, LEN(buffer)
            
            DO N = 1, 3
                
                IF (buffer(I:I) == " ") EXIT
                IF (buffer(I:I) == junk(N:N)) THEN
                    
                    buffer(I:I) = " "
                    EXIT
                    
                END IF
                
            END DO
        
        END DO
        
    RETURN
    END SUBROUTINE FilterLine
  5. I compiled and ran the binary like this:
    Code:
    gfortran test.f90
    ./a.out
Best regards,
Bruno
Attached Files
File Type: zip test_reader_f90.zip (1.1 KB, 3 views)
wyldckat is offline   Reply With Quote

Old   September 8, 2013, 11:44
Default
  #8
Senior Member
 
musaddeque hossein
Join Date: Mar 2009
Posts: 250
Rep Power: 8
musahossein is on a distinguished road
very clever! thanks.
musahossein is offline   Reply With Quote

Reply

Tags
force.dat, interdymfoam, libforces.so, sloshingtank2d

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
what is swap4foam ?? AB08 OpenFOAM 27 July 1, 2013 09:17
fluentMeshToFoam multidomain mesh conversion problem Attesz OpenFOAM Other Meshers: ICEM, Star, Ansys, Pointwise, GridPro, Ansa, ... 12 May 2, 2013 10:52
"parabolicVelocity" in OpenFoam 2.1.0 ? sawyer86 OpenFOAM Running, Solving & CFD 21 February 7, 2012 11:44
mesh airfoil NACA0012 anand_30 OpenFOAM Meshing & Mesh Conversion 12 December 12, 2011 04:16
DxFoam reader update hjasak OpenFOAM Post-Processing 69 April 24, 2008 01:24


All times are GMT -4. The time now is 06:42.